Kate’s DVG code

message("Loading packages")
Loading packages
library('ggplot2')
library('readr')
library('reshape2')
library('ggpubr')
library('plyr')
library('tidyverse')
library('dplyr')
library('glue')
library('ggVennDiagram')
# paramters used when running divrge
grouping_param = 5
match_length_param = 28
readLength = 150

# deletion read count cutoffs
count_cut = 30

# only looking at index and direct cases
keeping = c('index','direct')
message("Setting work directory and input file names")
Setting work directory and input file names
wkdir = "/Users/marissaknoll/Desktop/GitHub/Obesity/NewExtractions/H9N2/DVGs"
setwd(wkdir)
if (!dir.exists(glue("{wkdir}/DVG_figures"))) {
        dir.create(glue("{wkdir}/DVG_figures"))
      }

saveitdir = glue("{wkdir}/DVG_figures")
source(glue('{wkdir}/scripts/obese_PlotPrep.R'))
# loading in metadata and coverage data
metafile = glue("{wkdir}/scripts/transmission_h9n2_use_long.csv")
meta = read.csv(file=metafile,header=T,sep=",",na.strings = c('')) 
coverage_passfile = glue('{wkdir}/scripts/H9N2.coverage.pass.check.200.0.95.csv')
cov_check = read.csv(file=coverage_passfile,header=T,sep=",",na.strings = c(''))
# filter for samples that either pass with a yes OR has good average coverage and percentage cov at 200x is > 80
cov_filt_names = cov_check %>% filter(pass == 'YES' | 
                                      mean_coverage >= 200  | 
                                      percentage > 0.4) %>% 
            select(name, segment) %>% 
            unique()

# check segment count
cov_filt_names = cov_filt_names %>% group_by(name) %>% add_tally(name = 'segment_tally') %>% 
                    ungroup() %>% 
                    filter(segment_tally == 8) %>% 
                    unique() 

pull_names = c(levels(factor(cov_filt_names$name)))  # list to pull names from
dvgfile = glue('{wkdir}/H9N2.DVG.FINAL.OneGap.N5.Mis2.M28.G5.csv') # dvg file
dvg = read.csv(file=dvgfile,header=T,sep=",",na.strings = c(''))

dvg = dvg %>% filter(name %in% pull_names) # filter for samples that pass our coverage checks
dvg$sample = dvg$name  # generate new column so we can separate
dvg = dvg %>% separate(sample, c('new','cohort','ferret_id','dpi','rep'), '_')  # separate into info
Warning: Expected 5 pieces. Missing pieces filled with `NA` in 40841 rows [200561, 200562, 200563, 200564, 200565, 200566, 200567, 200568, 200569, 200570, 200571, 200572, 200573, 200574, 200575, 200576, 200577, 200578, 200579, 200580, ...].
CONTROLS = dvg %>% filter(ferret_id == 'HK1073')  # pulling out controls
CONTROLS$rep = CONTROLS$dpi
CONTROLS$dpi = 'stock'  # adding in stock info

dvg = dvg %>% filter(!name %in% c(levels(factor(CONTROLS$name)))) %>% unique()

dvg = rbind(dvg, CONTROLS) # rbind everything so it is all in one dataframe
# prepping rep information
dvg = dvg %>% select(-SegTotalDVG) %>% filter(DVG_freq >= count_cut) %>% unique()  # filter for those that pass cutoffs
rep1 = dvg %>% filter(rep == 'rep1') %>% unique()
rep2 = dvg %>% filter(rep == 'rep2') %>% unique()
# merge reps into one
dvg_reps = merge(rep1, rep2, by = c('cohort','ferret_id','dpi',
                                   'segment','segment_size','strain',
                                   'DVG_group','NewGap',
                                   'NewStart','NewEnd','GroupBoundaries',
                                   'DeletionSize','EstimatedFragLength'), all = TRUE) %>% unique()
# add in zeros
dvg_reps$DVG_freq.x[is.na(dvg_reps$DVG_freq.x)] = 0
dvg_reps$DVG_freq.y[is.na(dvg_reps$DVG_freq.y)] = 0
ggplot(dvg_reps, aes(x=DVG_freq.x, y=DVG_freq.y)) + 
    geom_point() + 
    PlotTheme1

# number of samples?
levels(factor(dvg_reps$ferret_id)) %>% length()
[1] 42
# reorder by segment size
SEGMENTS = c('H9N2_PB2', 'H9N2_PB1',
            'H9N2_PA','H9N2_HA','H9N2_NP', 
            'H9N2_NA','H9N2_MP','H9N2_NS')

cov_check$segment = factor(cov_check$segment, levels = SEGMENTS)
cov_check %>% 
    filter(name %in% pull_names) %>%
    ggplot(., aes(x= segment, y = mean_coverage)) + 
    geom_boxplot() + 
    PlotTheme1


cov_check %>% 
    filter(name %in% pull_names) %>%
    ggplot(., aes(x= segment, y = median_coverage)) + 
    geom_boxplot() + 
    PlotTheme1


cov_check %>% 
    filter(name %in% pull_names) %>%
    ggplot(., aes(x= segment, y = percentage)) + 
    geom_boxplot() + 
    PlotTheme1

df = cov_filt_names %>% select(-segment, -segment_tally) %>% unique()

df$sample = df$name

df = df %>% separate(sample, c('new','cohort','ferret_id','dpi','rep'), '_')
Warning: Expected 5 pieces. Missing pieces filled with `NA` in 10 rows [35, 36, 50, 72, 85, 154, 166, 171, 188, 202].
CONTROLS = df %>% filter(ferret_id == 'HK1073')

CONTROLS$rep = CONTROLS$dpi

CONTROLS$dpi = 'stock'


df = df %>% filter(!name %in% c(levels(factor(CONTROLS$name)))) %>% unique()

df = rbind(df, CONTROLS)

r1 = df %>% filter(rep == 'rep1') %>% select(-new) %>% unique()
r2 = df %>% filter(rep == 'rep2') %>% select(-new) %>% unique()
reps = merge(r1, r2, by = c('cohort','ferret_id','dpi')) %>% unique()


# these are the samples that only had one rep!
setdiff(levels(factor(r1$ferret_id)),
       levels(factor(r2$ferret_id)))
[1] "1411" "1972" "2244"
setdiff(meta$ferret_id, reps$ferret_id)  # samples in meta not in seq data
 [1] "1793" "1803" "1788" "1805" "1795" "1790" "1796" "1911" "1982" "1978" "1985" "1979" "1971" "1987" "1967" "1976" "1915" "2244"
[19] "2230" "2235" "2237" "2246" "2242" "2241" "2238" "2867" "2869" "2868" "2870" "1413"
setdiff(reps$ferret_id, meta$ferret_id) # samples in seq data not in meta
[1] "1966" "1969" "1968" "1417"
m = merge(reps, meta, by = c('ferret_id'), all = TRUE)

write.csv(m, glue('{wkdir}/scripts/UPDATED.H9N2.metadata.csv'), row.names = FALSE)
temp = meta %>% 
        filter(type %in% c('index','direct')) %>% 
        unique() %>% 
        select(pair, type, ferret_id) %>% unique() %>% 
        pivot_wider(names_from = 'type', values_from = 'ferret_id')

temp = rbind(temp, c('AD','stock','stock'))

temp$pair_ids = paste0(temp$index,'>',temp$direct)

temp = temp  %>% select(pair, pair_ids) %>% unique()

m = merge(m, temp, by = c('pair'))  # add in additional information to metadata to work with
# type check - only stock index direct
print(levels(factor(m$type)))
[1] "aerosol"   "direct"    "index"     "secondary" "stock"    
m$type = factor(m$type, levels = c('stock','index','direct'))
p1 = m %>% filter(ferret_id != 'HK1073') %>% unique() %>% 
    ggplot(., aes(x= dpi, y = pair_ids, fill = ferret_weight)) + 
    geom_tile(color = 'black') + 
    PlotTheme3 +
    weight_colFill + 
    facet_grid(index_direct~type, scales = 'free', space = 'free')

print(p1)

ggsave(p1,
       filename = glue("{wkdir}/DVG_figures/final.samples.pdf"),
       width = 6,
       height = 6, limitsize=FALSE, useDingbats = FALSE)

ggsave(p1,
       filename = glue("{wkdir}/DVG_figures/final.samples.png"),
       width = 6,
       height = 6, limitsize=FALSE) #, useDingbats = FALSE)

dvg_reps = dvg_reps %>% 
            filter(DVG_freq.x > count_cut & DVG_freq.y > count_cut) %>% 
        unique()   # make sure that both reps pass our cutoff

# add in variables for plotting
dvg_reps$ferret_day = paste0(dvg_reps$ferret_id, '_', dvg_reps$dpi)  

m$ferret_day = paste0(m$ferret_id, '_', m$dpi)
stock_temp = dvg_reps %>% filter(dpi == 'stock') %>%
    group_by(ferret_id, cohort, dpi, segment, name.x, name.y) %>%
    add_tally(name = 'seg_deletion_richness') %>%
    unique() %>%
    ungroup() %>% 
    group_by(ferret_id, dpi, name.x, name.y, cohort) %>% 
    add_tally(name = 'deletion_richness') %>%
    ungroup() %>% 
    unique()

s = stock_temp  # will use later

# filter down stock temp information
stock_temp = stock_temp %>% 
            select(ferret_id, dpi, cohort,ferret_day, segment, deletion_richness, seg_deletion_richness) %>%
            unique()


stock_temp = merge(stock_temp, m, by = c('ferret_id', 'dpi','cohort','ferret_day')) %>% 
    unique()
# filter out stock information, calculate dvg richness by segment and across genome for samples

dr = dvg_reps %>% 
            filter(dpi != 'stock') %>% 
            unique() %>% 
            group_by(ferret_id, dpi, segment, name.x, name.y, cohort) %>%
            add_tally(name = 'seg_deletion_richness') %>%
            ungroup() %>% 
            group_by(ferret_id, dpi, name.x, name.y, cohort) %>% 
            add_tally(name = 'deletion_richness') %>%
            ungroup() %>% 
            unique()

# filter down information so you don't have duplicates
richness = dr %>% 
            select(ferret_id, dpi, cohort,ferret_day, segment, deletion_richness, seg_deletion_richness) %>%
            unique()

# merge with metadata info
richness = merge(richness, m, by = c('ferret_id', 'dpi','cohort','ferret_day'), all.y = TRUE) %>%
    unique()

# make sure we filter out stock information (will add using the 's' dataframe generated above)
richness = richness %>% filter(dpi != 'stock')

reps_df = rbind(dr, s) # final reps richness df

reps_df = merge(reps_df, m, by = c('ferret_id','dpi','cohort','ferret_day'))  # add metadata
p4 = reps_df %>% 
    select(segment, NewGap, EstimatedFragLength, ferret_weight) %>%
    unique() %>%
    ggplot(., aes(x= EstimatedFragLength)) + 
    geom_histogram(color = 'black') + 
    PlotTheme1 +
    labs(x="estimated DVG frag. length (nt)", y='number of unique DVG species') 
print(p4)

ggsave(p4,
       filename = glue("{wkdir}/DVG_figures/deletion.size.pdf"),
       width = 5,
       height = 5, limitsize=FALSE, useDingbats = FALSE)

ggsave(p4,
       filename = glue("{wkdir}/DVG_figures/deletion.size.png"),
       width =5,
       height = 5, limitsize=FALSE) #, useDingbats = FALSE)


p4_alt = reps_df %>% 
    select(segment, NewGap, EstimatedFragLength, ferret_weight, type) %>%
    unique() %>%
    ggplot(., aes(x= EstimatedFragLength)) + 
    geom_histogram(color = 'black', binwidth = 50) + 
    facet_grid(type~ferret_weight) +
    PlotTheme1 +
    labs(x="estimated DVG frag. length (nt)", y='number of unique DVG species') 
print(p4_alt)
ggsave(p4_alt,
       filename = glue("{wkdir}/DVG_figures/deletion.size.bydiet.bytype.pdf"),
       width = 10,
       height = 5, limitsize=FALSE, useDingbats = FALSE)

lean_index =  reps_df %>% filter(type == 'index' & ferret_weight == 'lean') %>% 
                unique() %>%
                group_by(NewGap, segment, NewStart, NewEnd) %>%
            add_tally(name = 'lean_deletion_count') %>%
    ungroup() %>%
    select(NewGap, segment, lean_deletion_count) %>%
    unique()


obese_index =  reps_df %>% filter(type == 'index' & ferret_weight == 'obese') %>% 
                unique() %>%
                group_by(NewGap, segment, NewStart, NewEnd) %>%
            add_tally(name = 'obese_deletion_count') %>%
    ungroup() %>%
    select(NewGap, segment, obese_deletion_count) %>%
    unique()


df = merge(lean_index, obese_index, by = c('NewGap','segment'), all = TRUE) 

head(df)

df$lean_deletion_count[is.na(df$lean_deletion_count)] = 0

df$obese_deletion_count[is.na(df$obese_deletion_count)] = 0
p8 = reps_df %>% filter(type == 'index') %>% 
                unique() %>%
                group_by(NewGap, segment, NewStart, NewEnd) %>%
            add_tally(name = 'sample_count') %>%
    ungroup() %>%
    select(NewGap, segment,sample_count) %>%
    unique()  %>%
    ggplot(., aes(x=sample_count, y = ..count../sum(..count..))) +
    geom_histogram(color ='black') + 
    labs(x='number of samples with DVG type', y='proportion of DVGs in dataset (index only)') + 
    PlotTheme1 

print(p8)
ggsave(p8,
       filename = glue("{wkdir}/DVG_figures/sample.count.histo.pdf"),
       width = 5,
       height = 5, limitsize=FALSE, useDingbats = FALSE)

ggsave(p8,
       filename = glue("{wkdir}/DVG_figures/sample.count.histo.png"),
       width =5,
       height = 5, limitsize=FALSE) #, useDingbats = FALSE)

reps_df$ave_dvg_freq = (reps_df$DVG_freq.x + reps_df$DVG_freq.y)/2
reps_df = reps_df %>%
  arrange(ferret_day, ave_dvg_freq) %>% 
  group_by(ferret_day) %>% 
  mutate(order_number = row_number()) %>% 
  ungroup() %>%
  unique()
reps_df %>% 
    group_by(NewGap, segment, type, ferret_weight) %>%
    mutate(mean_order = mean(order_number),
          sample_count = n(),
          min_order = min(order_number),
          max_order = max(order_number),
          median_ord = median(order_number)) %>%
    ungroup() %>%
    unique() %>%
    select(segment, NewGap, mean_order, sample_count, min_order, max_order, median_ord, type, ferret_weight) %>%
    filter(sample_count > 1) %>%
    unique() %>%
    ggplot(., aes(y=mean_order, x = sample_count)) + 
    geom_point() + 
    PlotTheme1 + 
    facet_grid(.~ferret_weight + type)

top_ten = reps_df %>% filter(order_number %in% c(1, 2,3 ,4, 5, 6, 7, 8, 9, 10)) %>% unique()

head(top_ten)

length(levels(factor(top_ten$NewGap)))
[1] 433
max(df$lean_deletion_count)
[1] 22
max(df$obese_deletion_count)
[1] 21
p9 = ggplot(df, aes(x=lean_deletion_count, y = obese_deletion_count)) + 
    geom_jitter(width = 0.1, height = 0.1, alpha = 0.3) + 
    geom_hline(yintercept = 0, linetype = 2, color = 'black') +
    geom_hline(yintercept = 25, linetype = 2, color = 'red') +
    geom_vline(xintercept = 0, linetype = 2, color = 'black') +
    geom_vline(xintercept = 17, linetype = 2, color = 'red') +
    labs(x= 'number of lean samples with DVG', y='number of obese samples with DVG') + 
    PlotTheme1 

print(p9)
ggsave(p9,
       filename = glue("{wkdir}/DVG_figures/sample.count.lean.v.obese.pdf"),
       width = 5,
       height = 5, limitsize=FALSE, useDingbats = FALSE)

ggsave(p9,
       filename = glue("{wkdir}/DVG_figures/sample.count.lean.v.obese.png"),
       width =5,
       height = 5, limitsize=FALSE) #, useDingbats = FALSE)

reps_df %>% filter(type == 'index' & ferret_weight == 'obese') %>% select(name.x.x) %>% unique() %>% nrow()
[1] 25
reps_df %>% filter(type == 'index' & ferret_weight == 'lean') %>% select(name.x.x) %>% unique() %>% nrow()
[1] 23
richness = rbind(richness, stock_temp)
richness$deletion_richness[is.na(richness$deletion_richness)] = 0
DAYS = c('stock','d02','d04','d06','d08','d10','d12')
richness$cohort = gsub("FCC","Sp19",richness$cohort)
richness$dpi = factor(richness$dpi, levels = DAYS)
richness %>% filter(dpi %in% c('d02','d04')) %>%
        filter(type == 'index' | type == 'stock') %>%
    select(ferret_id, dpi, deletion_richness, type, ferret_weight, index_direct, cohort) %>%
    unique() %>%
    group_by(ferret_id) %>%
    add_tally(name = 'n') %>%
    ungroup() %>%
    filter(n >= 2) %>% 
    ungroup() %>%
    unique() %>%
    ggplot(., aes(x=dpi, y = deletion_richness, color = cohort, group=ferret_id, shape = ferret_weight)) + 
    #geom_boxplot() + 
    geom_line() + 
    geom_point(size = 2) + 
    PlotTheme1 +
    scale_color_brewer(palette = 'Set1')

    #weight_colScale + 
    #facet_grid(.~cohort)


p7 = richness %>% filter(dpi %in% c('d02','d04','d06')) %>%
        filter(type == 'index' | type == 'stock') %>%    
    select(ferret_id, dpi, deletion_richness, type, ferret_weight, index_direct, cohort) %>%
    unique() %>%
    group_by(ferret_id) %>%
    add_tally(name = 'n') %>%
    ungroup() %>%
    filter(n >= 2) %>% 
    ungroup() %>%
    unique() %>%
    ggplot(., aes(x=dpi, y = deletion_richness, color = ferret_weight, group=ferret_id, shape = ferret_weight)) + 
    #geom_boxplot() + 
    geom_line() + 
    geom_point(size = 2) + 
    PlotTheme1 +
    weight_colScale
    #facet_grid(.~cohort)

print(p7)
ggsave(p7,
       filename = glue("{wkdir}/DVG_figures/richness.index.pdf"),
       width = 5,
       height = 5, limitsize=FALSE, useDingbats = FALSE)

ggsave(p7,
       filename = glue("{wkdir}/DVG_figures/richness.index.png"),
       width =5,
       height = 5, limitsize=FALSE) #, useDingbats = FALSE)

colnames(richness)
 [1] "ferret_id"             "dpi"                   "cohort"                "ferret_day"            "segment"              
 [6] "deletion_richness"     "seg_deletion_richness" "pair"                  "name.x"                "rep.x"                
[11] "name.y"                "rep.y"                 "ferret_weight"         "type"                  "flag"                 
[16] "chain_position"        "notes"                 "index_direct"          "worked"                "pair_ids"             
order_typeday = c('stock','index_d02','index_d04',
                 'index_d06','index_d08','index_d10',
                 'index_d12',
                 'direct_d02','direct_d04',
                 'direct_d06','direct_d08','direct_d10',
                 'direct_d12')
richness$type_day = paste0(richness$type, '_', richness$dpi)
richness$type_day = factor(richness$type_day, levels = order_typeday)

p2 = richness %>% filter(ferret_weight == 'obese' & index_direct == 'obese_obese') %>%
    select(ferret_id, dpi, deletion_richness, type, ferret_weight, 
           pair_ids, index_direct, type_day) %>%
    ungroup() %>%
    unique() %>%
    ggplot(., aes(x=type_day, y = deletion_richness, color = pair_ids, group=pair_ids)) + 
    #geom_boxplot() + 
    geom_line(size = 1) + 
    geom_point(size = 2) + 
    labs(x='dpi (by index case)', y='DVG richness') + 
    PlotTheme1 +
    scale_color_brewer(palette = 'Set2') #+
    #weight_colScale + 
    #facet_grid(.~type)

print(p2)
ggsave(p2,
       filename = glue("{wkdir}/DVG_figures/obese.to.obese.diversity.pdf"),
       width = 8,
       height = 6, limitsize=FALSE, useDingbats = FALSE)

ggsave(p2,
       filename = glue("{wkdir}/DVG_figures/obese.to.obese.diversity.png"),
       width =8,
       height = 6, limitsize=FALSE) #, useDingbats = FALSE)

gen_rich = richness %>% 
  select(ferret_id, dpi, cohort,deletion_richness, type, ferret_weight, pair_ids, index_direct, type_day) %>%
  unique()

head(gen_rich)

gen_rich %>% filter(dpi %in% c('d02','d04','d06','stock')) %>%
    filter(type == 'index' | type == "stock") %>%
    ggplot(., aes(x=ferret_weight, y = deletion_richness, group = ferret_weight)) + 
    geom_boxplot(outlier.shape = NA) + 
    geom_jitter(width = 0.2, aes(color = ferret_weight)) +
    labs(x='segment',y='deletion richness') + 
    PlotTheme1 +
    weight_colScale +
    facet_grid(.~dpi)

Test for significance

o = filter(gen_rich, type == "index" & dpi == "d06" & ferret_weight == "obese")
l = filter(gen_rich, type == "index" & dpi == "d06" & ferret_weight == "lean")
t.test(o$deletion_richness,l$deletion_richness)

    Welch Two Sample t-test

data:  o$deletion_richness and l$deletion_richness
t = -0.10776, df = 5.4092, p-value = 0.9181
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -69.72324  63.98990
sample estimates:
mean of x mean of y 
 58.33333  61.20000 
seg_rich = richness %>% #filter(ferret_weight == 'obese' & index_direct == 'obese_obese') %>%
    select(ferret_id, dpi, seg_deletion_richness, type, ferret_weight, 
           pair_ids, index_direct, type_day, segment) %>%
    unique()

head(seg_rich)

temp = seg_rich %>% select(ferret_id, dpi, type, ferret_weight, pair_ids, type_day, index_direct) %>% unique()
temp$H9N2_PB2 = 0
temp$H9N2_PB1 = 0
temp$H9N2_PA = 0
temp$H9N2_HA = 0
temp$H9N2_NP = 0
temp$H9N2_NA = 0
temp$H9N2_MP = 0
temp$H9N2_NS = 0

temp = pivot_longer(temp, cols = all_of(SEGMENTS), names_to = 'segment') %>% select(-value)

seg_rich = merge(seg_rich, temp, by = c('ferret_id', 'dpi', 'type', 'ferret_weight', 
           'pair_ids', 'index_direct', 'type_day', 'segment'), all = TRUE) 

seg_rich$seg_deletion_richness[is.na(seg_rich$seg_deletion_richness)] = 0

seg_rich$segment = factor(seg_rich$segment, levels = SEGMENTS)
head(seg_rich)
p3 = seg_rich %>% filter(segment %in% SEGMENTS) %>%
    ggplot(., aes(x=segment, y = seg_deletion_richness)) + 
    geom_boxplot() + 
    labs(x='segment',y='deletion richness') + 
    PlotTheme1 

print(p3)

ggsave(p3,
       filename = glue("{wkdir}/DVG_figures/segment.richness.pdf"),
       width = 5,
       height = 5, limitsize=FALSE, useDingbats = FALSE)

ggsave(p3,
       filename = glue("{wkdir}/DVG_figures/segment.richness.png"),
       width =5,
       height = 5, limitsize=FALSE) #, useDingbats = FALSE)

seg_rich$seg_weight = paste0(seg_rich$segment, '_', seg_rich$ferret_weight)
seg_rich$ferret_weight = factor(seg_rich$ferret_weight, levels = c('stock','lean','obese'))
seg_rich %>% filter(segment %in% SEGMENTS) %>%
    ggplot(., aes(x=segment, y = seg_deletion_richness, group = seg_weight, color = ferret_weight)) + 
    geom_boxplot() + 
    labs(x='segment',y='deletion richness') + 
    PlotTheme1 +
    weight_colScale +
    facet_grid(.~type)



p6 = seg_rich %>% filter(segment %in% SEGMENTS & dpi %in% c('d02','d04','d06','stock')) %>%
    filter(type == 'index' | type == "stock") %>%
    ggplot(., aes(x=segment, y = seg_deletion_richness, group = seg_weight, color = ferret_weight)) + 
    geom_boxplot(outlier.shape = NA) + 
    labs(x='segment',y='deletion richness') + 
    PlotTheme1 +
    weight_colScale +
    facet_grid(.~dpi)

print(p6)

ggsave(p6,
       filename = glue("{wkdir}/DVG_figures/segment.index.richness.pdf"),
       width = 8,
       height = 4, limitsize=FALSE, useDingbats = FALSE)

ggsave(p6,
       filename = glue("{wkdir}/DVG_figures/segment.index.richness.png"),
       width =8,
       height = 4, limitsize=FALSE) #, useDingbats = FALSE)

NA
NA

Test for significance

o = filter(seg_rich, type == "index" & dpi == "d02" & segment == "H9N2_PB2" & ferret_weight == "obese")
l = filter(seg_rich, type == "index" & dpi == "d02" & segment == "H9N2_PB2" & ferret_weight == "lean")
t.test(o$seg_deletion_richness,l$seg_deletion_richness)

    Welch Two Sample t-test

data:  o$seg_deletion_richness and l$seg_deletion_richness
t = -2.247, df = 16.998, p-value = 0.03821
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -23.906617  -0.752474
sample estimates:
mean of x mean of y 
 10.54545  22.87500 
seg_rich %>% filter(type == 'index' &  segment %in% SEGMENTS) %>%
    ungroup() %>%
    unique() %>%
    ggplot(., aes(x=type_day, y = seg_deletion_richness, color = segment, group=segment)) + 
    #geom_boxplot() + 
    geom_line(size = 1) + 
    geom_point(size = 2) + 
    labs(x='dpi (by index case)', y='DVG richness') + 
    PlotTheme1 +
    scale_color_brewer(palette = 'Set2') +
    #weight_colScale + 
    facet_grid(.~ferret_weight + ferret_id, scales = 'free', space = 'free')

p4 = seg_rich %>% filter(ferret_weight == 'obese' & index_direct == 'obese_obese' & segment %in% SEGMENTS) %>%
    ungroup() %>%
    unique() %>%
    ggplot(., aes(x=type_day, y = seg_deletion_richness, color = segment, group=segment)) + 
    #geom_boxplot() + 
    geom_line(size = 1) + 
    geom_point(size = 2) + 
    labs(x='dpi (by index case)', y='DVG richness') + 
    PlotTheme1 +
    scale_color_brewer(palette = 'Set2') +
    #weight_colScale + 
    facet_grid(.~pair_ids, scales = 'free', space = 'free')

print(p4)


ggsave(p4,
       filename = glue("{wkdir}/DVG_figures/segment.obese.to.obese.richness.pdf"),
       width = 12,
       height = 4, limitsize=FALSE, useDingbats = FALSE)

ggsave(p4,
       filename = glue("{wkdir}/DVG_figures/segment.obese.to.obese.richness.png"),
       width =12,
       height = 4, limitsize=FALSE) #, useDingbats = FALSE)

End of Kate’s code

Which DVGs are shared between stock and index?

reps_df$DVG = paste0(reps_df$segment,"_",reps_df$DVG_group)

F17_stock = filter(reps_df ,type == "stock", cohort == "F17")
F17_stock_dvg = unique(F17_stock$DVG)
W17_stock = filter(reps_df ,type == "stock", cohort == "W17")
W17_stock_dvg = unique(W17_stock$DVG)
Sm18_stock = filter(reps_df ,type == "stock", cohort == "Sm18")
Sm18_stock_dvg = unique(Sm18_stock$DVG)
Sp19_stock = filter(reps_df ,type == "stock", cohort == "Sp19")
Sp19_stock_dvg = unique(Sp19_stock$DVG)
Sp20_stock = filter(reps_df ,type == "stock", cohort == "Sp20")
Sp20_stock_dvg = unique(Sp20_stock$DVG)

F17_index = filter(reps_df ,type == "index", cohort == "F17")
F17_index_dvg = unique(F17_index$DVG)
W17_index = filter(reps_df ,type == "index", cohort == "W17")
W17_index_dvg = unique(W17_index$DVG)
Sm18_index = filter(reps_df ,type == "index", cohort == "Sm18")
Sm18_index_dvg = unique(Sm18_index$DVG)
Sp19_index = filter(reps_df ,type == "index", cohort == "Sp19")
Sp19_index_dvg = unique(Sp19_index$DVG)
Sp20_index = filter(reps_df ,type == "index", cohort == "Sp20")
Sp20_index_dvg = unique(Sp20_index$DVG)

F17_shared = F17_index %>% filter(DVG %in% F17_stock_dvg) %>% filter((DVG %in% F17_index_dvg)) %>% unique()
F17_denovo = F17_index %>% filter((DVG %in% F17_index_dvg)) %>% filter(!(DVG %in% F17_stock_dvg)) %>% unique()

W17_shared = W17_index %>% filter(DVG %in% W17_stock_dvg) %>% filter((DVG %in% W17_index_dvg)) %>% unique()
W17_denovo = W17_index %>% filter((DVG %in% W17_index_dvg)) %>% filter(!(DVG %in% W17_stock_dvg)) %>% unique()

Sm18_shared = Sm18_index %>% filter(DVG %in% Sm18_stock_dvg) %>% filter((DVG %in% Sm18_index_dvg)) %>% unique()
Sm18_denovo = Sm18_index %>% filter((DVG %in% Sm18_index_dvg)) %>% filter(!(DVG %in% Sm18_stock_dvg)) %>% unique()

Sp19_shared = Sp19_index %>% filter(DVG %in% Sp19_stock_dvg) %>% filter((DVG %in% Sp19_index_dvg)) %>% unique()
Sp19_denovo = Sp19_index %>% filter((DVG %in% Sp19_index_dvg)) %>% filter(!(DVG %in% Sp19_stock_dvg)) %>% unique()

Sp20_shared = Sp20_index %>% filter(DVG %in% Sp20_stock_dvg) %>% filter((DVG %in% Sp20_index_dvg)) %>% unique() # still not working
Sp20_denovo = Sp20_index %>% filter((DVG %in% Sp20_index_dvg)) %>% filter(!(DVG %in% Sp20_stock_dvg)) %>% unique() # still not working

stock_shared = rbind(F17_shared,W17_shared,Sm18_shared,Sp19_shared,Sp20_shared)
index_unique = rbind(F17_denovo,W17_denovo,Sm18_denovo,Sp19_denovo,Sp20_denovo)
stock_obese = filter(stock_shared, ferret_weight == "obese") 
o_dvg = unique(stock_obese$DVG)

stock_lean = filter(stock_shared, ferret_weight == "lean") 
l_dvg = unique(stock_lean$DVG)

stock_dvg <- list(Obese = o_dvg, Lean = l_dvg)

StockDVGs = ggVennDiagram(stock_dvg)
print(StockDVGs)
ggsave(StockDVGs, file = "StockDVGs.pdf", path = saveitdir)
Saving 7.29 x 4.51 in image

ShockSharedDVGs = ggplot(stock_shared, aes(x = dpi, y = DVG)) +
  geom_point() +
  geom_line(aes(group = DVG)) +
  facet_grid(~segment) +
  PlotTheme1
print(ShockSharedDVGs)
ggsave(ShockSharedDVGs, file = "ShockSharedDVGs.pdf", path = saveitdir)
Saving 7.29 x 4.51 in image

Are there diet-specific DVGs in index ferrets?

index_obese = filter(index_unique, ferret_weight == "obese") 
o_dvg = unique(index_obese$DVG)

index_lean = filter(index_unique, ferret_weight == "lean") 
l_dvg = unique(index_lean$DVG)

diet_dvg <- list(Obese = o_dvg, Lean = l_dvg)

DietUniqueDVGs = ggVennDiagram(diet_dvg)
print(DietUniqueDVGs)
ggsave(DietUniqueDVGs, file = "DietUniqueDVGs.pdf", path = saveitdir)
Saving 7.29 x 4.51 in image

Pulling out diet-specific DVGs

lean = index_lean %>% 
  filter(DVG %in% l_dvg) %>% 
  filter(!(DVG %in% o_dvg)) %>%
  unique()

lean = lean %>%
  group_by(DVG) %>% 
  mutate(count = 1, totalsamp = sum(count))

mult_lean = filter(lean, totalsamp > 1) %>% 
  unique()

obese = index_unique %>% 
  filter((DVG %in% o_dvg)) %>%
  filter(!(DVG %in% l_dvg)) %>% 
  unique()

obese = obese %>%
  group_by(DVG) %>% 
  mutate(count = 1, totalsamp = sum(count))

mult_obese = filter(obese, totalsamp > 1) %>% 
  unique()
ggplot(lean, aes(x = DVG)) +
  geom_histogram(stat = "count")
Warning: Ignoring unknown parameters: `binwidth`, `bins`, and `pad`

LeanDVGs = ggplot(lean, aes(y = DVG)) +
  geom_point(aes(x = NewStart)) +
  geom_point(aes(x = NewEnd)) +
  facet_grid(~factor(segment, levels = SEGMENTS)) +
  PlotTheme1
print(LeanDVGs)
ggsave(LeanDVGs, file = "LeanDVGs.pdf", path = saveitdir)
Saving 7.29 x 4.51 in image

ggplot(lean, aes(x = dpi, y = DVG)) +
  geom_point() +
  geom_line(aes(group = DVG)) +
  facet_grid(~factor(segment, levels = SEGMENTS)) +
  PlotTheme1


ggplot(mult_lean, aes(x = dpi, y = DVG)) +
  geom_point() +
  geom_line(aes(group = DVG)) +
  facet_grid(~factor(segment, levels = SEGMENTS)) +
  PlotTheme1


ggplot(obese, aes(x = DVG)) +
  geom_histogram(stat = "count")
Warning: Ignoring unknown parameters: `binwidth`, `bins`, and `pad`

ObeseDVGs = ggplot(obese, aes(y = DVG)) +
  geom_point(aes(x = NewStart)) +
  geom_point(aes(x = NewEnd)) +
  facet_grid(~factor(segment, levels = SEGMENTS)) +
  PlotTheme1
print(ObeseDVGs)
ggsave(ObeseDVGs, file = "ObeseDVGs.pdf", path = saveitdir)
Saving 7.29 x 4.51 in image

ggplot(obese, aes(x = dpi, y = DVG)) +
  geom_point() +
  geom_line(aes(group = DVG)) +
  facet_grid(~factor(segment, levels = SEGMENTS)) +
  PlotTheme1


ggplot(mult_obese, aes(x = dpi, y = DVG)) +
  geom_point() +
  geom_line(aes(group = DVG)) +
  facet_grid(~factor(segment, levels = SEGMENTS)) +
  PlotTheme1

Are DVGs transmitted

ggplot(reps_df, aes(x = ))

LS0tCnRpdGxlOiAiRFZHX0FuYWx5c2lzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpLYXRlJ3MgRFZHIGNvZGUKCmBgYHtyfQptZXNzYWdlKCJMb2FkaW5nIHBhY2thZ2VzIikKbGlicmFyeSgnZ2dwbG90MicpCmxpYnJhcnkoJ3JlYWRyJykKbGlicmFyeSgncmVzaGFwZTInKQpsaWJyYXJ5KCdnZ3B1YnInKQpsaWJyYXJ5KCdwbHlyJykKbGlicmFyeSgndGlkeXZlcnNlJykKbGlicmFyeSgnZHBseXInKQpsaWJyYXJ5KCdnbHVlJykKbGlicmFyeSgnZ2dWZW5uRGlhZ3JhbScpCmBgYAoKYGBge3J9CiMgcGFyYW10ZXJzIHVzZWQgd2hlbiBydW5uaW5nIGRpdnJnZQpncm91cGluZ19wYXJhbSA9IDUKbWF0Y2hfbGVuZ3RoX3BhcmFtID0gMjgKcmVhZExlbmd0aCA9IDE1MAoKIyBkZWxldGlvbiByZWFkIGNvdW50IGN1dG9mZnMKY291bnRfY3V0ID0gMzAKCiMgb25seSBsb29raW5nIGF0IGluZGV4IGFuZCBkaXJlY3QgY2FzZXMKa2VlcGluZyA9IGMoJ2luZGV4JywnZGlyZWN0JykKYGBgCgpgYGB7cn0KbWVzc2FnZSgiU2V0dGluZyB3b3JrIGRpcmVjdG9yeSBhbmQgaW5wdXQgZmlsZSBuYW1lcyIpCndrZGlyID0gIi9Vc2Vycy9tYXJpc3Nha25vbGwvRGVza3RvcC9HaXRIdWIvT2Jlc2l0eS9OZXdFeHRyYWN0aW9ucy9IOU4yL0RWR3MiCnNldHdkKHdrZGlyKQpgYGAKCmBgYHtyfQppZiAoIWRpci5leGlzdHMoZ2x1ZSgie3drZGlyfS9EVkdfZmlndXJlcyIpKSkgewogICAgICAgIGRpci5jcmVhdGUoZ2x1ZSgie3drZGlyfS9EVkdfZmlndXJlcyIpKQogICAgICB9CgpzYXZlaXRkaXIgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzIikKYGBgCgpgYGB7cn0Kc291cmNlKGdsdWUoJ3t3a2Rpcn0vc2NyaXB0cy9vYmVzZV9QbG90UHJlcC5SJykpCmBgYAoKYGBge3J9CiMgbG9hZGluZyBpbiBtZXRhZGF0YSBhbmQgY292ZXJhZ2UgZGF0YQptZXRhZmlsZSA9IGdsdWUoInt3a2Rpcn0vc2NyaXB0cy90cmFuc21pc3Npb25faDluMl91c2VfbG9uZy5jc3YiKQptZXRhID0gcmVhZC5jc3YoZmlsZT1tZXRhZmlsZSxoZWFkZXI9VCxzZXA9IiwiLG5hLnN0cmluZ3MgPSBjKCcnKSkgCm1ldGEgPSBmaWx0ZXIobWV0YW0gZmxhZyA9PSAia2VlcCIpCmNvdmVyYWdlX3Bhc3NmaWxlID0gZ2x1ZSgne3drZGlyfS9zY3JpcHRzL0g5TjIuY292ZXJhZ2UucGFzcy5jaGVjay4yMDAuMC45NS5jc3YnKQpjb3ZfY2hlY2sgPSByZWFkLmNzdihmaWxlPWNvdmVyYWdlX3Bhc3NmaWxlLGhlYWRlcj1ULHNlcD0iLCIsbmEuc3RyaW5ncyA9IGMoJycpKQpgYGAKCmBgYHtyfQojIGZpbHRlciBmb3Igc2FtcGxlcyB0aGF0IGVpdGhlciBwYXNzIHdpdGggYSB5ZXMgT1IgaGFzIGdvb2QgYXZlcmFnZSBjb3ZlcmFnZSBhbmQgcGVyY2VudGFnZSBjb3YgYXQgMjAweCBpcyA+IDgwCmNvdl9maWx0X25hbWVzID0gY292X2NoZWNrICU+JSBmaWx0ZXIocGFzcyA9PSAnWUVTJyB8IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW5fY292ZXJhZ2UgPj0gMjAwICB8IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2UgPiAwLjQpICU+JSAKICAgICAgICAgICAgc2VsZWN0KG5hbWUsIHNlZ21lbnQpICU+JSAKICAgICAgICAgICAgdW5pcXVlKCkKCiMgY2hlY2sgc2VnbWVudCBjb3VudApjb3ZfZmlsdF9uYW1lcyA9IGNvdl9maWx0X25hbWVzICU+JSBncm91cF9ieShuYW1lKSAlPiUgYWRkX3RhbGx5KG5hbWUgPSAnc2VnbWVudF90YWxseScpICU+JSAKICAgICAgICAgICAgICAgICAgICB1bmdyb3VwKCkgJT4lIAogICAgICAgICAgICAgICAgICAgIGZpbHRlcihzZWdtZW50X3RhbGx5ID09IDgpICU+JSAKICAgICAgICAgICAgICAgICAgICB1bmlxdWUoKSAKCnB1bGxfbmFtZXMgPSBjKGxldmVscyhmYWN0b3IoY292X2ZpbHRfbmFtZXMkbmFtZSkpKSAgIyBsaXN0IHRvIHB1bGwgbmFtZXMgZnJvbQpgYGAKCmBgYHtyfQpkdmdmaWxlID0gZ2x1ZSgne3drZGlyfS9IOU4yLkRWRy5GSU5BTC5PbmVHYXAuTjUuTWlzMi5NMjguRzUuY3N2JykgIyBkdmcgZmlsZQpkdmcgPSByZWFkLmNzdihmaWxlPWR2Z2ZpbGUsaGVhZGVyPVQsc2VwPSIsIixuYS5zdHJpbmdzID0gYygnJykpCgpkdmcgPSBkdmcgJT4lIGZpbHRlcihuYW1lICVpbiUgcHVsbF9uYW1lcykgIyBmaWx0ZXIgZm9yIHNhbXBsZXMgdGhhdCBwYXNzIG91ciBjb3ZlcmFnZSBjaGVja3MKZHZnJHNhbXBsZSA9IGR2ZyRuYW1lICAjIGdlbmVyYXRlIG5ldyBjb2x1bW4gc28gd2UgY2FuIHNlcGFyYXRlCmR2ZyA9IGR2ZyAlPiUgc2VwYXJhdGUoc2FtcGxlLCBjKCduZXcnLCdjb2hvcnQnLCdmZXJyZXRfaWQnLCdkcGknLCdyZXAnKSwgJ18nKSAgIyBzZXBhcmF0ZSBpbnRvIGluZm8KCkNPTlRST0xTID0gZHZnICU+JSBmaWx0ZXIoZmVycmV0X2lkID09ICdISzEwNzMnKSAgIyBwdWxsaW5nIG91dCBjb250cm9scwpDT05UUk9MUyRyZXAgPSBDT05UUk9MUyRkcGkKQ09OVFJPTFMkZHBpID0gJ3N0b2NrJyAgIyBhZGRpbmcgaW4gc3RvY2sgaW5mbwoKZHZnID0gZHZnICU+JSBmaWx0ZXIoIW5hbWUgJWluJSBjKGxldmVscyhmYWN0b3IoQ09OVFJPTFMkbmFtZSkpKSkgJT4lIHVuaXF1ZSgpCgpkdmcgPSByYmluZChkdmcsIENPTlRST0xTKSAjIHJiaW5kIGV2ZXJ5dGhpbmcgc28gaXQgaXMgYWxsIGluIG9uZSBkYXRhZnJhbWUKYGBgCgpgYGB7cn0KIyBwcmVwcGluZyByZXAgaW5mb3JtYXRpb24KZHZnID0gZHZnICU+JSBzZWxlY3QoLVNlZ1RvdGFsRFZHKSAlPiUgZmlsdGVyKERWR19mcmVxID49IGNvdW50X2N1dCkgJT4lIHVuaXF1ZSgpICAjIGZpbHRlciBmb3IgdGhvc2UgdGhhdCBwYXNzIGN1dG9mZnMKcmVwMSA9IGR2ZyAlPiUgZmlsdGVyKHJlcCA9PSAncmVwMScpICU+JSB1bmlxdWUoKQpyZXAyID0gZHZnICU+JSBmaWx0ZXIocmVwID09ICdyZXAyJykgJT4lIHVuaXF1ZSgpCmBgYAoKYGBge3J9CiMgbWVyZ2UgcmVwcyBpbnRvIG9uZQpkdmdfcmVwcyA9IG1lcmdlKHJlcDEsIHJlcDIsIGJ5ID0gYygnY29ob3J0JywnZmVycmV0X2lkJywnZHBpJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2VnbWVudCcsJ3NlZ21lbnRfc2l6ZScsJ3N0cmFpbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0RWR19ncm91cCcsJ05ld0dhcCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ05ld1N0YXJ0JywnTmV3RW5kJywnR3JvdXBCb3VuZGFyaWVzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRGVsZXRpb25TaXplJywnRXN0aW1hdGVkRnJhZ0xlbmd0aCcpLCBhbGwgPSBUUlVFKSAlPiUgdW5pcXVlKCkKYGBgCgpgYGB7cn0KIyBhZGQgaW4gemVyb3MKZHZnX3JlcHMkRFZHX2ZyZXEueFtpcy5uYShkdmdfcmVwcyREVkdfZnJlcS54KV0gPSAwCmR2Z19yZXBzJERWR19mcmVxLnlbaXMubmEoZHZnX3JlcHMkRFZHX2ZyZXEueSldID0gMApgYGAKCmBgYHtyfQpnZ3Bsb3QoZHZnX3JlcHMsIGFlcyh4PURWR19mcmVxLngsIHk9RFZHX2ZyZXEueSkpICsgCiAgICBnZW9tX3BvaW50KCkgKyAKICAgIFBsb3RUaGVtZTEKYGBgCgpgYGB7cn0KIyBudW1iZXIgb2Ygc2FtcGxlcz8KbGV2ZWxzKGZhY3RvcihkdmdfcmVwcyRmZXJyZXRfaWQpKSAlPiUgbGVuZ3RoKCkKYGBgCgpgYGB7cn0KIyByZW9yZGVyIGJ5IHNlZ21lbnQgc2l6ZQpTRUdNRU5UUyA9IGMoJ0g5TjJfUEIyJywgJ0g5TjJfUEIxJywKICAgICAgICAgICAgJ0g5TjJfUEEnLCdIOU4yX0hBJywnSDlOMl9OUCcsIAogICAgICAgICAgICAnSDlOMl9OQScsJ0g5TjJfTVAnLCdIOU4yX05TJykKCmNvdl9jaGVjayRzZWdtZW50ID0gZmFjdG9yKGNvdl9jaGVjayRzZWdtZW50LCBsZXZlbHMgPSBTRUdNRU5UUykKYGBgCgpgYGB7cn0KY292X2NoZWNrICU+JSAKICAgIGZpbHRlcihuYW1lICVpbiUgcHVsbF9uYW1lcykgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9IHNlZ21lbnQsIHkgPSBtZWFuX2NvdmVyYWdlKSkgKyAKICAgIGdlb21fYm94cGxvdCgpICsgCiAgICBQbG90VGhlbWUxCgpjb3ZfY2hlY2sgJT4lIAogICAgZmlsdGVyKG5hbWUgJWluJSBwdWxsX25hbWVzKSAlPiUKICAgIGdncGxvdCguLCBhZXMoeD0gc2VnbWVudCwgeSA9IG1lZGlhbl9jb3ZlcmFnZSkpICsgCiAgICBnZW9tX2JveHBsb3QoKSArIAogICAgUGxvdFRoZW1lMQoKY292X2NoZWNrICU+JSAKICAgIGZpbHRlcihuYW1lICVpbiUgcHVsbF9uYW1lcykgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9IHNlZ21lbnQsIHkgPSBwZXJjZW50YWdlKSkgKyAKICAgIGdlb21fYm94cGxvdCgpICsgCiAgICBQbG90VGhlbWUxCmBgYAoKYGBge3J9CmRmID0gY292X2ZpbHRfbmFtZXMgJT4lIHNlbGVjdCgtc2VnbWVudCwgLXNlZ21lbnRfdGFsbHkpICU+JSB1bmlxdWUoKQoKZGYkc2FtcGxlID0gZGYkbmFtZQoKZGYgPSBkZiAlPiUgc2VwYXJhdGUoc2FtcGxlLCBjKCduZXcnLCdjb2hvcnQnLCdmZXJyZXRfaWQnLCdkcGknLCdyZXAnKSwgJ18nKQoKQ09OVFJPTFMgPSBkZiAlPiUgZmlsdGVyKGZlcnJldF9pZCA9PSAnSEsxMDczJykKCkNPTlRST0xTJHJlcCA9IENPTlRST0xTJGRwaQoKQ09OVFJPTFMkZHBpID0gJ3N0b2NrJwoKCmRmID0gZGYgJT4lIGZpbHRlcighbmFtZSAlaW4lIGMobGV2ZWxzKGZhY3RvcihDT05UUk9MUyRuYW1lKSkpKSAlPiUgdW5pcXVlKCkKCmRmID0gcmJpbmQoZGYsIENPTlRST0xTKQoKcjEgPSBkZiAlPiUgZmlsdGVyKHJlcCA9PSAncmVwMScpICU+JSBzZWxlY3QoLW5ldykgJT4lIHVuaXF1ZSgpCnIyID0gZGYgJT4lIGZpbHRlcihyZXAgPT0gJ3JlcDInKSAlPiUgc2VsZWN0KC1uZXcpICU+JSB1bmlxdWUoKQpyZXBzID0gbWVyZ2UocjEsIHIyLCBieSA9IGMoJ2NvaG9ydCcsJ2ZlcnJldF9pZCcsJ2RwaScpKSAlPiUgdW5pcXVlKCkKCgojIHRoZXNlIGFyZSB0aGUgc2FtcGxlcyB0aGF0IG9ubHkgaGFkIG9uZSByZXAhCnNldGRpZmYobGV2ZWxzKGZhY3RvcihyMSRmZXJyZXRfaWQpKSwKICAgICAgIGxldmVscyhmYWN0b3IocjIkZmVycmV0X2lkKSkpCmBgYAoKYGBge3J9CnNldGRpZmYobWV0YSRmZXJyZXRfaWQsIHJlcHMkZmVycmV0X2lkKSAgIyBzYW1wbGVzIGluIG1ldGEgbm90IGluIHNlcSBkYXRhCnNldGRpZmYocmVwcyRmZXJyZXRfaWQsIG1ldGEkZmVycmV0X2lkKSAjIHNhbXBsZXMgaW4gc2VxIGRhdGEgbm90IGluIG1ldGEKCm0gPSBtZXJnZShyZXBzLCBtZXRhLCBieSA9IGMoJ2ZlcnJldF9pZCcpLCBhbGwgPSBUUlVFKQoKd3JpdGUuY3N2KG0sIGdsdWUoJ3t3a2Rpcn0vc2NyaXB0cy9VUERBVEVELkg5TjIubWV0YWRhdGEuY3N2JyksIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCmBgYHtyfQp0ZW1wID0gbWV0YSAlPiUgCiAgICAgICAgZmlsdGVyKHR5cGUgJWluJSBjKCdpbmRleCcsJ2RpcmVjdCcpKSAlPiUgCiAgICAgICAgdW5pcXVlKCkgJT4lIAogICAgICAgIHNlbGVjdChwYWlyLCB0eXBlLCBmZXJyZXRfaWQpICU+JSB1bmlxdWUoKSAlPiUgCiAgICAgICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9ICd0eXBlJywgdmFsdWVzX2Zyb20gPSAnZmVycmV0X2lkJykKCnRlbXAgPSByYmluZCh0ZW1wLCBjKCdaJywnc3RvY2snLCdzdG9jaycpKQoKdGVtcCRwYWlyX2lkcyA9IHBhc3RlMCh0ZW1wJGluZGV4LCc+Jyx0ZW1wJGRpcmVjdCkKCnRlbXAgPSB0ZW1wICAlPiUgc2VsZWN0KHBhaXIsIHBhaXJfaWRzKSAlPiUgdW5pcXVlKCkKCm0gPSBtZXJnZShtLCB0ZW1wLCBieSA9IGMoJ3BhaXInKSkgICMgYWRkIGluIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdG8gbWV0YWRhdGEgdG8gd29yayB3aXRoCmBgYAoKYGBge3J9CiMgdHlwZSBjaGVjayAtIG9ubHkgc3RvY2sgaW5kZXggZGlyZWN0CnByaW50KGxldmVscyhmYWN0b3IobSR0eXBlKSkpCmBgYAoKYGBge3J9Cm0kdHlwZSA9IGZhY3RvcihtJHR5cGUsIGxldmVscyA9IGMoJ3N0b2NrJywnaW5kZXgnLCdkaXJlY3QnKSkKYGBgCgpgYGB7cn0KcDEgPSBtICU+JSBmaWx0ZXIoZmVycmV0X2lkICE9ICdISzEwNzMnKSAlPiUgdW5pcXVlKCkgJT4lIAogICAgZ2dwbG90KC4sIGFlcyh4PSBkcGksIHkgPSBwYWlyX2lkcywgZmlsbCA9IGZlcnJldF93ZWlnaHQpKSArIAogICAgZ2VvbV90aWxlKGNvbG9yID0gJ2JsYWNrJykgKyAKICAgIFBsb3RUaGVtZTMgKwogICAgd2VpZ2h0X2NvbEZpbGwgKyAKICAgIGZhY2V0X2dyaWQoaW5kZXhfZGlyZWN0fnR5cGUsIHNjYWxlcyA9ICdmcmVlJywgc3BhY2UgPSAnZnJlZScpCgpwcmludChwMSkKCmdnc2F2ZShwMSwKICAgICAgIGZpbGVuYW1lID0gZ2x1ZSgie3drZGlyfS9EVkdfZmlndXJlcy9maW5hbC5zYW1wbGVzLnBkZiIpLAogICAgICAgd2lkdGggPSA2LAogICAgICAgaGVpZ2h0ID0gNiwgbGltaXRzaXplPUZBTFNFLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQoKZ2dzYXZlKHAxLAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL2ZpbmFsLnNhbXBsZXMucG5nIiksCiAgICAgICB3aWR0aCA9IDYsCiAgICAgICBoZWlnaHQgPSA2LCBsaW1pdHNpemU9RkFMU0UpICMsIHVzZURpbmdiYXRzID0gRkFMU0UpCmBgYAoKYGBge3J9CmR2Z19yZXBzID0gZHZnX3JlcHMgJT4lIAogICAgICAgICAgICBmaWx0ZXIoRFZHX2ZyZXEueCA+IGNvdW50X2N1dCAmIERWR19mcmVxLnkgPiBjb3VudF9jdXQpICU+JSAKICAgICAgICB1bmlxdWUoKSAgICMgbWFrZSBzdXJlIHRoYXQgYm90aCByZXBzIHBhc3Mgb3VyIGN1dG9mZgoKIyBhZGQgaW4gdmFyaWFibGVzIGZvciBwbG90dGluZwpkdmdfcmVwcyRmZXJyZXRfZGF5ID0gcGFzdGUwKGR2Z19yZXBzJGZlcnJldF9pZCwgJ18nLCBkdmdfcmVwcyRkcGkpICAKCm0kZmVycmV0X2RheSA9IHBhc3RlMChtJGZlcnJldF9pZCwgJ18nLCBtJGRwaSkKYGBgCgpgYGB7cn0Kc3RvY2tfdGVtcCA9IGR2Z19yZXBzICU+JSBmaWx0ZXIoZHBpID09ICdzdG9jaycpICU+JQogICAgZ3JvdXBfYnkoZmVycmV0X2lkLCBjb2hvcnQsIGRwaSwgc2VnbWVudCwgbmFtZS54LCBuYW1lLnkpICU+JQogICAgYWRkX3RhbGx5KG5hbWUgPSAnc2VnX2RlbGV0aW9uX3JpY2huZXNzJykgJT4lCiAgICB1bmlxdWUoKSAlPiUKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBncm91cF9ieShmZXJyZXRfaWQsIGRwaSwgbmFtZS54LCBuYW1lLnksIGNvaG9ydCkgJT4lIAogICAgYWRkX3RhbGx5KG5hbWUgPSAnZGVsZXRpb25fcmljaG5lc3MnKSAlPiUKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICB1bmlxdWUoKQoKcyA9IHN0b2NrX3RlbXAgICMgd2lsbCB1c2UgbGF0ZXIKCiMgZmlsdGVyIGRvd24gc3RvY2sgdGVtcCBpbmZvcm1hdGlvbgpzdG9ja190ZW1wID0gc3RvY2tfdGVtcCAlPiUgCiAgICAgICAgICAgIHNlbGVjdChmZXJyZXRfaWQsIGRwaSwgY29ob3J0LGZlcnJldF9kYXksIHNlZ21lbnQsIGRlbGV0aW9uX3JpY2huZXNzLCBzZWdfZGVsZXRpb25fcmljaG5lc3MpICU+JQogICAgICAgICAgICB1bmlxdWUoKQoKCnN0b2NrX3RlbXAgPSBtZXJnZShzdG9ja190ZW1wLCBtLCBieSA9IGMoJ2ZlcnJldF9pZCcsICdkcGknLCdjb2hvcnQnLCdmZXJyZXRfZGF5JykpICU+JSAKICAgIHVuaXF1ZSgpCmBgYAoKYGBge3J9CiMgZmlsdGVyIG91dCBzdG9jayBpbmZvcm1hdGlvbiwgY2FsY3VsYXRlIGR2ZyByaWNobmVzcyBieSBzZWdtZW50IGFuZCBhY3Jvc3MgZ2Vub21lIGZvciBzYW1wbGVzCgpkciA9IGR2Z19yZXBzICU+JSAKICAgICAgICAgICAgZmlsdGVyKGRwaSAhPSAnc3RvY2snKSAlPiUgCiAgICAgICAgICAgIHVuaXF1ZSgpICU+JSAKICAgICAgICAgICAgZ3JvdXBfYnkoZmVycmV0X2lkLCBkcGksIHNlZ21lbnQsIG5hbWUueCwgbmFtZS55LCBjb2hvcnQpICU+JQogICAgICAgICAgICBhZGRfdGFsbHkobmFtZSA9ICdzZWdfZGVsZXRpb25fcmljaG5lc3MnKSAlPiUKICAgICAgICAgICAgdW5ncm91cCgpICU+JSAKICAgICAgICAgICAgZ3JvdXBfYnkoZmVycmV0X2lkLCBkcGksIG5hbWUueCwgbmFtZS55LCBjb2hvcnQpICU+JSAKICAgICAgICAgICAgYWRkX3RhbGx5KG5hbWUgPSAnZGVsZXRpb25fcmljaG5lc3MnKSAlPiUKICAgICAgICAgICAgdW5ncm91cCgpICU+JSAKICAgICAgICAgICAgdW5pcXVlKCkKCiMgZmlsdGVyIGRvd24gaW5mb3JtYXRpb24gc28geW91IGRvbid0IGhhdmUgZHVwbGljYXRlcwpyaWNobmVzcyA9IGRyICU+JSAKICAgICAgICAgICAgc2VsZWN0KGZlcnJldF9pZCwgZHBpLCBjb2hvcnQsZmVycmV0X2RheSwgc2VnbWVudCwgZGVsZXRpb25fcmljaG5lc3MsIHNlZ19kZWxldGlvbl9yaWNobmVzcykgJT4lCiAgICAgICAgICAgIHVuaXF1ZSgpCgojIG1lcmdlIHdpdGggbWV0YWRhdGEgaW5mbwpyaWNobmVzcyA9IG1lcmdlKHJpY2huZXNzLCBtLCBieSA9IGMoJ2ZlcnJldF9pZCcsICdkcGknLCdjb2hvcnQnLCdmZXJyZXRfZGF5JyksIGFsbC55ID0gVFJVRSkgJT4lCiAgICB1bmlxdWUoKQoKIyBtYWtlIHN1cmUgd2UgZmlsdGVyIG91dCBzdG9jayBpbmZvcm1hdGlvbiAod2lsbCBhZGQgdXNpbmcgdGhlICdzJyBkYXRhZnJhbWUgZ2VuZXJhdGVkIGFib3ZlKQpyaWNobmVzcyA9IHJpY2huZXNzICU+JSBmaWx0ZXIoZHBpICE9ICdzdG9jaycpCgpyZXBzX2RmID0gcmJpbmQoZHIsIHMpICMgZmluYWwgcmVwcyByaWNobmVzcyBkZgoKcmVwc19kZiA9IG1lcmdlKHJlcHNfZGYsIG0sIGJ5ID0gYygnZmVycmV0X2lkJywnZHBpJywnY29ob3J0JywnZmVycmV0X2RheScpKSAgIyBhZGQgbWV0YWRhdGEKYGBgCgpgYGB7cn0KcDQgPSByZXBzX2RmICU+JSAKICAgIHNlbGVjdChzZWdtZW50LCBOZXdHYXAsIEVzdGltYXRlZEZyYWdMZW5ndGgsIGZlcnJldF93ZWlnaHQpICU+JQogICAgdW5pcXVlKCkgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9IEVzdGltYXRlZEZyYWdMZW5ndGgpKSArIAogICAgZ2VvbV9oaXN0b2dyYW0oY29sb3IgPSAnYmxhY2snKSArIAogICAgUGxvdFRoZW1lMSArCiAgICBsYWJzKHg9ImVzdGltYXRlZCBEVkcgZnJhZy4gbGVuZ3RoIChudCkiLCB5PSdudW1iZXIgb2YgdW5pcXVlIERWRyBzcGVjaWVzJykgCnByaW50KHA0KQoKZ2dzYXZlKHA0LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL2RlbGV0aW9uLnNpemUucGRmIiksCiAgICAgICB3aWR0aCA9IDUsCiAgICAgICBoZWlnaHQgPSA1LCBsaW1pdHNpemU9RkFMU0UsIHVzZURpbmdiYXRzID0gRkFMU0UpCgpnZ3NhdmUocDQsCiAgICAgICBmaWxlbmFtZSA9IGdsdWUoInt3a2Rpcn0vRFZHX2ZpZ3VyZXMvZGVsZXRpb24uc2l6ZS5wbmciKSwKICAgICAgIHdpZHRoID01LAogICAgICAgaGVpZ2h0ID0gNSwgbGltaXRzaXplPUZBTFNFKSAjLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQoKcDRfYWx0ID0gcmVwc19kZiAlPiUgCiAgICBzZWxlY3Qoc2VnbWVudCwgTmV3R2FwLCBFc3RpbWF0ZWRGcmFnTGVuZ3RoLCBmZXJyZXRfd2VpZ2h0LCB0eXBlKSAlPiUKICAgIHVuaXF1ZSgpICU+JQogICAgZ2dwbG90KC4sIGFlcyh4PSBFc3RpbWF0ZWRGcmFnTGVuZ3RoKSkgKyAKICAgIGdlb21faGlzdG9ncmFtKGNvbG9yID0gJ2JsYWNrJywgYmlud2lkdGggPSA1MCkgKyAKICAgIGZhY2V0X2dyaWQodHlwZX5mZXJyZXRfd2VpZ2h0KSArCiAgICBQbG90VGhlbWUxICsKICAgIGxhYnMoeD0iZXN0aW1hdGVkIERWRyBmcmFnLiBsZW5ndGggKG50KSIsIHk9J251bWJlciBvZiB1bmlxdWUgRFZHIHNwZWNpZXMnKSAKcHJpbnQocDRfYWx0KQpnZ3NhdmUocDRfYWx0LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL2RlbGV0aW9uLnNpemUuYnlkaWV0LmJ5dHlwZS5wZGYiKSwKICAgICAgIHdpZHRoID0gMTAsCiAgICAgICBoZWlnaHQgPSA1LCBsaW1pdHNpemU9RkFMU0UsIHVzZURpbmdiYXRzID0gRkFMU0UpCgpgYGAKCmBgYHtyfQpsZWFuX2luZGV4ID0gIHJlcHNfZGYgJT4lIGZpbHRlcih0eXBlID09ICdpbmRleCcgJiBmZXJyZXRfd2VpZ2h0ID09ICdsZWFuJykgJT4lIAogICAgICAgICAgICAgICAgdW5pcXVlKCkgJT4lCiAgICAgICAgICAgICAgICBncm91cF9ieShOZXdHYXAsIHNlZ21lbnQsIE5ld1N0YXJ0LCBOZXdFbmQpICU+JQogICAgICAgICAgICBhZGRfdGFsbHkobmFtZSA9ICdsZWFuX2RlbGV0aW9uX2NvdW50JykgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBzZWxlY3QoTmV3R2FwLCBzZWdtZW50LCBsZWFuX2RlbGV0aW9uX2NvdW50KSAlPiUKICAgIHVuaXF1ZSgpCgoKb2Jlc2VfaW5kZXggPSAgcmVwc19kZiAlPiUgZmlsdGVyKHR5cGUgPT0gJ2luZGV4JyAmIGZlcnJldF93ZWlnaHQgPT0gJ29iZXNlJykgJT4lIAogICAgICAgICAgICAgICAgdW5pcXVlKCkgJT4lCiAgICAgICAgICAgICAgICBncm91cF9ieShOZXdHYXAsIHNlZ21lbnQsIE5ld1N0YXJ0LCBOZXdFbmQpICU+JQogICAgICAgICAgICBhZGRfdGFsbHkobmFtZSA9ICdvYmVzZV9kZWxldGlvbl9jb3VudCcpICU+JQogICAgdW5ncm91cCgpICU+JQogICAgc2VsZWN0KE5ld0dhcCwgc2VnbWVudCwgb2Jlc2VfZGVsZXRpb25fY291bnQpICU+JQogICAgdW5pcXVlKCkKCgpkZiA9IG1lcmdlKGxlYW5faW5kZXgsIG9iZXNlX2luZGV4LCBieSA9IGMoJ05ld0dhcCcsJ3NlZ21lbnQnKSwgYWxsID0gVFJVRSkgCgpoZWFkKGRmKQoKZGYkbGVhbl9kZWxldGlvbl9jb3VudFtpcy5uYShkZiRsZWFuX2RlbGV0aW9uX2NvdW50KV0gPSAwCgpkZiRvYmVzZV9kZWxldGlvbl9jb3VudFtpcy5uYShkZiRvYmVzZV9kZWxldGlvbl9jb3VudCldID0gMApgYGAKCmBgYHtyfQpwOCA9IHJlcHNfZGYgJT4lIGZpbHRlcih0eXBlID09ICdpbmRleCcpICU+JSAKICAgICAgICAgICAgICAgIHVuaXF1ZSgpICU+JQogICAgICAgICAgICAgICAgZ3JvdXBfYnkoTmV3R2FwLCBzZWdtZW50LCBOZXdTdGFydCwgTmV3RW5kKSAlPiUKICAgICAgICAgICAgYWRkX3RhbGx5KG5hbWUgPSAnc2FtcGxlX2NvdW50JykgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBzZWxlY3QoTmV3R2FwLCBzZWdtZW50LHNhbXBsZV9jb3VudCkgJT4lCiAgICB1bmlxdWUoKSAgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9c2FtcGxlX2NvdW50LCB5ID0gLi5jb3VudC4uL3N1bSguLmNvdW50Li4pKSkgKwogICAgZ2VvbV9oaXN0b2dyYW0oY29sb3IgPSdibGFjaycpICsgCiAgICBsYWJzKHg9J251bWJlciBvZiBzYW1wbGVzIHdpdGggRFZHIHR5cGUnLCB5PSdwcm9wb3J0aW9uIG9mIERWR3MgaW4gZGF0YXNldCAoaW5kZXggb25seSknKSArIAogICAgUGxvdFRoZW1lMSAKCnByaW50KHA4KQpnZ3NhdmUocDgsCiAgICAgICBmaWxlbmFtZSA9IGdsdWUoInt3a2Rpcn0vRFZHX2ZpZ3VyZXMvc2FtcGxlLmNvdW50Lmhpc3RvLnBkZiIpLAogICAgICAgd2lkdGggPSA1LAogICAgICAgaGVpZ2h0ID0gNSwgbGltaXRzaXplPUZBTFNFLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQoKZ2dzYXZlKHA4LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL3NhbXBsZS5jb3VudC5oaXN0by5wbmciKSwKICAgICAgIHdpZHRoID01LAogICAgICAgaGVpZ2h0ID0gNSwgbGltaXRzaXplPUZBTFNFKSAjLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQpgYGAKCmBgYHtyfQpyZXBzX2RmJGF2ZV9kdmdfZnJlcSA9IChyZXBzX2RmJERWR19mcmVxLnggKyByZXBzX2RmJERWR19mcmVxLnkpLzIKYGBgCgpgYGB7cn0KcmVwc19kZiA9IHJlcHNfZGYgJT4lCiAgYXJyYW5nZShmZXJyZXRfZGF5LCBhdmVfZHZnX2ZyZXEpICU+JSAKICBncm91cF9ieShmZXJyZXRfZGF5KSAlPiUgCiAgbXV0YXRlKG9yZGVyX251bWJlciA9IHJvd19udW1iZXIoKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUKICB1bmlxdWUoKQpgYGAKCmBgYHtyfQpyZXBzX2RmICU+JSAKICAgIGdyb3VwX2J5KE5ld0dhcCwgc2VnbWVudCwgdHlwZSwgZmVycmV0X3dlaWdodCkgJT4lCiAgICBtdXRhdGUobWVhbl9vcmRlciA9IG1lYW4ob3JkZXJfbnVtYmVyKSwKICAgICAgICAgIHNhbXBsZV9jb3VudCA9IG4oKSwKICAgICAgICAgIG1pbl9vcmRlciA9IG1pbihvcmRlcl9udW1iZXIpLAogICAgICAgICAgbWF4X29yZGVyID0gbWF4KG9yZGVyX251bWJlciksCiAgICAgICAgICBtZWRpYW5fb3JkID0gbWVkaWFuKG9yZGVyX251bWJlcikpICU+JQogICAgdW5ncm91cCgpICU+JQogICAgdW5pcXVlKCkgJT4lCiAgICBzZWxlY3Qoc2VnbWVudCwgTmV3R2FwLCBtZWFuX29yZGVyLCBzYW1wbGVfY291bnQsIG1pbl9vcmRlciwgbWF4X29yZGVyLCBtZWRpYW5fb3JkLCB0eXBlLCBmZXJyZXRfd2VpZ2h0KSAlPiUKICAgIGZpbHRlcihzYW1wbGVfY291bnQgPiAxKSAlPiUKICAgIHVuaXF1ZSgpICU+JQogICAgZ2dwbG90KC4sIGFlcyh5PW1lYW5fb3JkZXIsIHggPSBzYW1wbGVfY291bnQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBQbG90VGhlbWUxICsgCiAgICBmYWNldF9ncmlkKC5+ZmVycmV0X3dlaWdodCArIHR5cGUpCmBgYAoKYGBge3J9CnRvcF90ZW4gPSByZXBzX2RmICU+JSBmaWx0ZXIob3JkZXJfbnVtYmVyICVpbiUgYygxLCAyLDMgLDQsIDUsIDYsIDcsIDgsIDksIDEwKSkgJT4lIHVuaXF1ZSgpCgpoZWFkKHRvcF90ZW4pCgpsZW5ndGgobGV2ZWxzKGZhY3Rvcih0b3BfdGVuJE5ld0dhcCkpKQpgYGAKCmBgYHtyfQptYXgoZGYkbGVhbl9kZWxldGlvbl9jb3VudCkKbWF4KGRmJG9iZXNlX2RlbGV0aW9uX2NvdW50KQoKcDkgPSBnZ3Bsb3QoZGYsIGFlcyh4PWxlYW5fZGVsZXRpb25fY291bnQsIHkgPSBvYmVzZV9kZWxldGlvbl9jb3VudCkpICsgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSwgaGVpZ2h0ID0gMC4xLCBhbHBoYSA9IDAuMykgKyAKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAnYmxhY2snKSArCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyNSwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICdyZWQnKSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gJ2JsYWNrJykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMTcsIGxpbmV0eXBlID0gMiwgY29sb3IgPSAncmVkJykgKwogICAgbGFicyh4PSAnbnVtYmVyIG9mIGxlYW4gc2FtcGxlcyB3aXRoIERWRycsIHk9J251bWJlciBvZiBvYmVzZSBzYW1wbGVzIHdpdGggRFZHJykgKyAKICAgIFBsb3RUaGVtZTEgCgpwcmludChwOSkKZ2dzYXZlKHA5LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL3NhbXBsZS5jb3VudC5sZWFuLnYub2Jlc2UucGRmIiksCiAgICAgICB3aWR0aCA9IDUsCiAgICAgICBoZWlnaHQgPSA1LCBsaW1pdHNpemU9RkFMU0UsIHVzZURpbmdiYXRzID0gRkFMU0UpCgpnZ3NhdmUocDksCiAgICAgICBmaWxlbmFtZSA9IGdsdWUoInt3a2Rpcn0vRFZHX2ZpZ3VyZXMvc2FtcGxlLmNvdW50LmxlYW4udi5vYmVzZS5wbmciKSwKICAgICAgIHdpZHRoID01LAogICAgICAgaGVpZ2h0ID0gNSwgbGltaXRzaXplPUZBTFNFKSAjLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQpgYGAKCmBgYHtyfQpyZXBzX2RmICU+JSBmaWx0ZXIodHlwZSA9PSAnaW5kZXgnICYgZmVycmV0X3dlaWdodCA9PSAnb2Jlc2UnKSAlPiUgc2VsZWN0KG5hbWUueC54KSAlPiUgdW5pcXVlKCkgJT4lIG5yb3coKQpyZXBzX2RmICU+JSBmaWx0ZXIodHlwZSA9PSAnaW5kZXgnICYgZmVycmV0X3dlaWdodCA9PSAnbGVhbicpICU+JSBzZWxlY3QobmFtZS54LngpICU+JSB1bmlxdWUoKSAlPiUgbnJvdygpCmBgYAoKYGBge3J9CnJpY2huZXNzID0gcmJpbmQocmljaG5lc3MsIHN0b2NrX3RlbXApCnJpY2huZXNzJGRlbGV0aW9uX3JpY2huZXNzW2lzLm5hKHJpY2huZXNzJGRlbGV0aW9uX3JpY2huZXNzKV0gPSAwCkRBWVMgPSBjKCdzdG9jaycsJ2QwMicsJ2QwNCcsJ2QwNicsJ2QwOCcsJ2QxMCcsJ2QxMicpCmBgYAoKYGBge3J9CnJpY2huZXNzJGNvaG9ydCA9IGdzdWIoIkZDQyIsIlNwMTkiLHJpY2huZXNzJGNvaG9ydCkKcmljaG5lc3MkZHBpID0gZmFjdG9yKHJpY2huZXNzJGRwaSwgbGV2ZWxzID0gREFZUykKcmljaG5lc3MgJT4lIGZpbHRlcihkcGkgJWluJSBjKCdkMDInLCdkMDQnKSkgJT4lCiAgICAgICAgZmlsdGVyKHR5cGUgPT0gJ2luZGV4JyB8IHR5cGUgPT0gJ3N0b2NrJykgJT4lCiAgICBzZWxlY3QoZmVycmV0X2lkLCBkcGksIGRlbGV0aW9uX3JpY2huZXNzLCB0eXBlLCBmZXJyZXRfd2VpZ2h0LCBpbmRleF9kaXJlY3QsIGNvaG9ydCkgJT4lCiAgICB1bmlxdWUoKSAlPiUKICAgIGdyb3VwX2J5KGZlcnJldF9pZCkgJT4lCiAgICBhZGRfdGFsbHkobmFtZSA9ICduJykgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBmaWx0ZXIobiA+PSAyKSAlPiUgCiAgICB1bmdyb3VwKCkgJT4lCiAgICB1bmlxdWUoKSAlPiUKICAgIGdncGxvdCguLCBhZXMoeD1kcGksIHkgPSBkZWxldGlvbl9yaWNobmVzcywgY29sb3IgPSBjb2hvcnQsIGdyb3VwPWZlcnJldF9pZCwgc2hhcGUgPSBmZXJyZXRfd2VpZ2h0KSkgKyAKICAgICNnZW9tX2JveHBsb3QoKSArIAogICAgZ2VvbV9saW5lKCkgKyAKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiAgICBQbG90VGhlbWUxICsKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gJ1NldDEnKQogICAgI3dlaWdodF9jb2xTY2FsZSArIAogICAgI2ZhY2V0X2dyaWQoLn5jb2hvcnQpCgoKcDcgPSByaWNobmVzcyAlPiUgZmlsdGVyKGRwaSAlaW4lIGMoJ2QwMicsJ2QwNCcsJ2QwNicpKSAlPiUKICAgICAgICBmaWx0ZXIodHlwZSA9PSAnaW5kZXgnIHwgdHlwZSA9PSAnc3RvY2snKSAlPiUgICAgCiAgICBzZWxlY3QoZmVycmV0X2lkLCBkcGksIGRlbGV0aW9uX3JpY2huZXNzLCB0eXBlLCBmZXJyZXRfd2VpZ2h0LCBpbmRleF9kaXJlY3QsIGNvaG9ydCkgJT4lCiAgICB1bmlxdWUoKSAlPiUKICAgIGdyb3VwX2J5KGZlcnJldF9pZCkgJT4lCiAgICBhZGRfdGFsbHkobmFtZSA9ICduJykgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBmaWx0ZXIobiA+PSAyKSAlPiUgCiAgICB1bmdyb3VwKCkgJT4lCiAgICB1bmlxdWUoKSAlPiUKICAgIGdncGxvdCguLCBhZXMoeD1kcGksIHkgPSBkZWxldGlvbl9yaWNobmVzcywgY29sb3IgPSBmZXJyZXRfd2VpZ2h0LCBncm91cD1mZXJyZXRfaWQsIHNoYXBlID0gZmVycmV0X3dlaWdodCkpICsgCiAgICAjZ2VvbV9ib3hwbG90KCkgKyAKICAgIGdlb21fbGluZSgpICsgCiAgICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAogICAgUGxvdFRoZW1lMSArCiAgICB3ZWlnaHRfY29sU2NhbGUKICAgICNmYWNldF9ncmlkKC5+Y29ob3J0KQoKcHJpbnQocDcpCmdnc2F2ZShwNywKICAgICAgIGZpbGVuYW1lID0gZ2x1ZSgie3drZGlyfS9EVkdfZmlndXJlcy9yaWNobmVzcy5pbmRleC5wZGYiKSwKICAgICAgIHdpZHRoID0gNSwKICAgICAgIGhlaWdodCA9IDUsIGxpbWl0c2l6ZT1GQUxTRSwgdXNlRGluZ2JhdHMgPSBGQUxTRSkKCmdnc2F2ZShwNywKICAgICAgIGZpbGVuYW1lID0gZ2x1ZSgie3drZGlyfS9EVkdfZmlndXJlcy9yaWNobmVzcy5pbmRleC5wbmciKSwKICAgICAgIHdpZHRoID01LAogICAgICAgaGVpZ2h0ID0gNSwgbGltaXRzaXplPUZBTFNFKSAjLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQpgYGAKCmBgYHtyfQpjb2xuYW1lcyhyaWNobmVzcykKb3JkZXJfdHlwZWRheSA9IGMoJ3N0b2NrJywnaW5kZXhfZDAyJywnaW5kZXhfZDA0JywKICAgICAgICAgICAgICAgICAnaW5kZXhfZDA2JywnaW5kZXhfZDA4JywnaW5kZXhfZDEwJywKICAgICAgICAgICAgICAgICAnaW5kZXhfZDEyJywKICAgICAgICAgICAgICAgICAnZGlyZWN0X2QwMicsJ2RpcmVjdF9kMDQnLAogICAgICAgICAgICAgICAgICdkaXJlY3RfZDA2JywnZGlyZWN0X2QwOCcsJ2RpcmVjdF9kMTAnLAogICAgICAgICAgICAgICAgICdkaXJlY3RfZDEyJykKYGBgCgpgYGB7cn0KcmljaG5lc3MkdHlwZV9kYXkgPSBwYXN0ZTAocmljaG5lc3MkdHlwZSwgJ18nLCByaWNobmVzcyRkcGkpCnJpY2huZXNzJHR5cGVfZGF5ID0gZmFjdG9yKHJpY2huZXNzJHR5cGVfZGF5LCBsZXZlbHMgPSBvcmRlcl90eXBlZGF5KQoKcDIgPSByaWNobmVzcyAlPiUgZmlsdGVyKGZlcnJldF93ZWlnaHQgPT0gJ29iZXNlJyAmIGluZGV4X2RpcmVjdCA9PSAnb2Jlc2Vfb2Jlc2UnKSAlPiUKICAgIHNlbGVjdChmZXJyZXRfaWQsIGRwaSwgZGVsZXRpb25fcmljaG5lc3MsIHR5cGUsIGZlcnJldF93ZWlnaHQsIAogICAgICAgICAgIHBhaXJfaWRzLCBpbmRleF9kaXJlY3QsIHR5cGVfZGF5KSAlPiUKICAgIHVuZ3JvdXAoKSAlPiUKICAgIHVuaXF1ZSgpICU+JQogICAgZ2dwbG90KC4sIGFlcyh4PXR5cGVfZGF5LCB5ID0gZGVsZXRpb25fcmljaG5lc3MsIGNvbG9yID0gcGFpcl9pZHMsIGdyb3VwPXBhaXJfaWRzKSkgKyAKICAgICNnZW9tX2JveHBsb3QoKSArIAogICAgZ2VvbV9saW5lKHNpemUgPSAxKSArIAogICAgZ2VvbV9wb2ludChzaXplID0gMikgKyAKICAgIGxhYnMoeD0nZHBpIChieSBpbmRleCBjYXNlKScsIHk9J0RWRyByaWNobmVzcycpICsgCiAgICBQbG90VGhlbWUxICsKICAgIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gJ1NldDInKSAjKwogICAgI3dlaWdodF9jb2xTY2FsZSArIAogICAgI2ZhY2V0X2dyaWQoLn50eXBlKQoKcHJpbnQocDIpCmdnc2F2ZShwMiwKICAgICAgIGZpbGVuYW1lID0gZ2x1ZSgie3drZGlyfS9EVkdfZmlndXJlcy9vYmVzZS50by5vYmVzZS5kaXZlcnNpdHkucGRmIiksCiAgICAgICB3aWR0aCA9IDgsCiAgICAgICBoZWlnaHQgPSA2LCBsaW1pdHNpemU9RkFMU0UsIHVzZURpbmdiYXRzID0gRkFMU0UpCgpnZ3NhdmUocDIsCiAgICAgICBmaWxlbmFtZSA9IGdsdWUoInt3a2Rpcn0vRFZHX2ZpZ3VyZXMvb2Jlc2UudG8ub2Jlc2UuZGl2ZXJzaXR5LnBuZyIpLAogICAgICAgd2lkdGggPTgsCiAgICAgICBoZWlnaHQgPSA2LCBsaW1pdHNpemU9RkFMU0UpICMsIHVzZURpbmdiYXRzID0gRkFMU0UpCmBgYAoKYGBge3J9Cmdlbl9yaWNoID0gcmljaG5lc3MgJT4lIAogIHNlbGVjdChmZXJyZXRfaWQsIGRwaSwgY29ob3J0LGRlbGV0aW9uX3JpY2huZXNzLCB0eXBlLCBmZXJyZXRfd2VpZ2h0LCBwYWlyX2lkcywgaW5kZXhfZGlyZWN0LCB0eXBlX2RheSkgJT4lCiAgdW5pcXVlKCkKCmhlYWQoZ2VuX3JpY2gpCgpnZW5fcmljaCAlPiUgZmlsdGVyKGRwaSAlaW4lIGMoJ2QwMicsJ2QwNCcsJ2QwNicsJ3N0b2NrJykpICU+JQogICAgZmlsdGVyKHR5cGUgPT0gJ2luZGV4JyB8IHR5cGUgPT0gInN0b2NrIikgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9ZmVycmV0X3dlaWdodCwgeSA9IGRlbGV0aW9uX3JpY2huZXNzLCBncm91cCA9IGZlcnJldF93ZWlnaHQpKSArIAogICAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyAKICAgIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhZXMoY29sb3IgPSBmZXJyZXRfd2VpZ2h0KSkgKwogICAgbGFicyh4PSdzZWdtZW50Jyx5PSdkZWxldGlvbiByaWNobmVzcycpICsgCiAgICBQbG90VGhlbWUxICsKICAgIHdlaWdodF9jb2xTY2FsZSArCiAgICBmYWNldF9ncmlkKC5+ZHBpKQpgYGAKClRlc3QgZm9yIHNpZ25pZmljYW5jZQpgYGB7cn0KbyA9IGZpbHRlcihnZW5fcmljaCwgdHlwZSA9PSAiaW5kZXgiICYgZHBpID09ICJkMDYiICYgZmVycmV0X3dlaWdodCA9PSAib2Jlc2UiKQpsID0gZmlsdGVyKGdlbl9yaWNoLCB0eXBlID09ICJpbmRleCIgJiBkcGkgPT0gImQwNiIgJiBmZXJyZXRfd2VpZ2h0ID09ICJsZWFuIikKdC50ZXN0KG8kZGVsZXRpb25fcmljaG5lc3MsbCRkZWxldGlvbl9yaWNobmVzcykKYGBgCgpgYGB7cn0Kc2VnX3JpY2ggPSByaWNobmVzcyAlPiUgI2ZpbHRlcihmZXJyZXRfd2VpZ2h0ID09ICdvYmVzZScgJiBpbmRleF9kaXJlY3QgPT0gJ29iZXNlX29iZXNlJykgJT4lCiAgICBzZWxlY3QoZmVycmV0X2lkLCBkcGksIHNlZ19kZWxldGlvbl9yaWNobmVzcywgdHlwZSwgZmVycmV0X3dlaWdodCwgCiAgICAgICAgICAgcGFpcl9pZHMsIGluZGV4X2RpcmVjdCwgdHlwZV9kYXksIHNlZ21lbnQpICU+JQogICAgdW5pcXVlKCkKCmhlYWQoc2VnX3JpY2gpCgp0ZW1wID0gc2VnX3JpY2ggJT4lIHNlbGVjdChmZXJyZXRfaWQsIGRwaSwgdHlwZSwgZmVycmV0X3dlaWdodCwgcGFpcl9pZHMsIHR5cGVfZGF5LCBpbmRleF9kaXJlY3QpICU+JSB1bmlxdWUoKQp0ZW1wJEg5TjJfUEIyID0gMAp0ZW1wJEg5TjJfUEIxID0gMAp0ZW1wJEg5TjJfUEEgPSAwCnRlbXAkSDlOMl9IQSA9IDAKdGVtcCRIOU4yX05QID0gMAp0ZW1wJEg5TjJfTkEgPSAwCnRlbXAkSDlOMl9NUCA9IDAKdGVtcCRIOU4yX05TID0gMAoKdGVtcCA9IHBpdm90X2xvbmdlcih0ZW1wLCBjb2xzID0gYWxsX29mKFNFR01FTlRTKSwgbmFtZXNfdG8gPSAnc2VnbWVudCcpICU+JSBzZWxlY3QoLXZhbHVlKQoKc2VnX3JpY2ggPSBtZXJnZShzZWdfcmljaCwgdGVtcCwgYnkgPSBjKCdmZXJyZXRfaWQnLCAnZHBpJywgJ3R5cGUnLCAnZmVycmV0X3dlaWdodCcsIAogICAgICAgICAgICdwYWlyX2lkcycsICdpbmRleF9kaXJlY3QnLCAndHlwZV9kYXknLCAnc2VnbWVudCcpLCBhbGwgPSBUUlVFKSAKCnNlZ19yaWNoJHNlZ19kZWxldGlvbl9yaWNobmVzc1tpcy5uYShzZWdfcmljaCRzZWdfZGVsZXRpb25fcmljaG5lc3MpXSA9IDAKCnNlZ19yaWNoJHNlZ21lbnQgPSBmYWN0b3Ioc2VnX3JpY2gkc2VnbWVudCwgbGV2ZWxzID0gU0VHTUVOVFMpCmhlYWQoc2VnX3JpY2gpCmBgYAoKYGBge3J9CnAzID0gc2VnX3JpY2ggJT4lIGZpbHRlcihzZWdtZW50ICVpbiUgU0VHTUVOVFMpICU+JQogICAgZ2dwbG90KC4sIGFlcyh4PXNlZ21lbnQsIHkgPSBzZWdfZGVsZXRpb25fcmljaG5lc3MpKSArIAogICAgZ2VvbV9ib3hwbG90KCkgKyAKICAgIGxhYnMoeD0nc2VnbWVudCcseT0nZGVsZXRpb24gcmljaG5lc3MnKSArIAogICAgUGxvdFRoZW1lMSAKCnByaW50KHAzKQoKZ2dzYXZlKHAzLAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL3NlZ21lbnQucmljaG5lc3MucGRmIiksCiAgICAgICB3aWR0aCA9IDUsCiAgICAgICBoZWlnaHQgPSA1LCBsaW1pdHNpemU9RkFMU0UsIHVzZURpbmdiYXRzID0gRkFMU0UpCgpnZ3NhdmUocDMsCiAgICAgICBmaWxlbmFtZSA9IGdsdWUoInt3a2Rpcn0vRFZHX2ZpZ3VyZXMvc2VnbWVudC5yaWNobmVzcy5wbmciKSwKICAgICAgIHdpZHRoID01LAogICAgICAgaGVpZ2h0ID0gNSwgbGltaXRzaXplPUZBTFNFKSAjLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQpgYGAKCmBgYHtyfQpzZWdfcmljaCRzZWdfd2VpZ2h0ID0gcGFzdGUwKHNlZ19yaWNoJHNlZ21lbnQsICdfJywgc2VnX3JpY2gkZmVycmV0X3dlaWdodCkKc2VnX3JpY2gkZmVycmV0X3dlaWdodCA9IGZhY3RvcihzZWdfcmljaCRmZXJyZXRfd2VpZ2h0LCBsZXZlbHMgPSBjKCdzdG9jaycsJ2xlYW4nLCdvYmVzZScpKQpgYGAKCmBgYHtyfQpzZWdfcmljaCAlPiUgZmlsdGVyKHNlZ21lbnQgJWluJSBTRUdNRU5UUykgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9c2VnbWVudCwgeSA9IHNlZ19kZWxldGlvbl9yaWNobmVzcywgZ3JvdXAgPSBzZWdfd2VpZ2h0LCBjb2xvciA9IGZlcnJldF93ZWlnaHQpKSArIAogICAgZ2VvbV9ib3hwbG90KCkgKyAKICAgIGxhYnMoeD0nc2VnbWVudCcseT0nZGVsZXRpb24gcmljaG5lc3MnKSArIAogICAgUGxvdFRoZW1lMSArCiAgICB3ZWlnaHRfY29sU2NhbGUgKwogICAgZmFjZXRfZ3JpZCgufnR5cGUpCgoKcDYgPSBzZWdfcmljaCAlPiUgZmlsdGVyKHNlZ21lbnQgJWluJSBTRUdNRU5UUyAmIGRwaSAlaW4lIGMoJ2QwMicsJ2QwNCcsJ2QwNicsJ3N0b2NrJykpICU+JQogICAgZmlsdGVyKHR5cGUgPT0gJ2luZGV4JyB8IHR5cGUgPT0gInN0b2NrIikgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9c2VnbWVudCwgeSA9IHNlZ19kZWxldGlvbl9yaWNobmVzcywgZ3JvdXAgPSBzZWdfd2VpZ2h0LCBjb2xvciA9IGZlcnJldF93ZWlnaHQpKSArIAogICAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyAKICAgIGxhYnMoeD0nc2VnbWVudCcseT0nZGVsZXRpb24gcmljaG5lc3MnKSArIAogICAgUGxvdFRoZW1lMSArCiAgICB3ZWlnaHRfY29sU2NhbGUgKwogICAgZmFjZXRfZ3JpZCgufmRwaSkKCnByaW50KHA2KQoKZ2dzYXZlKHA2LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL3NlZ21lbnQuaW5kZXgucmljaG5lc3MucGRmIiksCiAgICAgICB3aWR0aCA9IDgsCiAgICAgICBoZWlnaHQgPSA0LCBsaW1pdHNpemU9RkFMU0UsIHVzZURpbmdiYXRzID0gRkFMU0UpCgpnZ3NhdmUocDYsCiAgICAgICBmaWxlbmFtZSA9IGdsdWUoInt3a2Rpcn0vRFZHX2ZpZ3VyZXMvc2VnbWVudC5pbmRleC5yaWNobmVzcy5wbmciKSwKICAgICAgIHdpZHRoID04LAogICAgICAgaGVpZ2h0ID0gNCwgbGltaXRzaXplPUZBTFNFKSAjLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQoKCmBgYApUZXN0IGZvciBzaWduaWZpY2FuY2UKYGBge3J9Cm8gPSBmaWx0ZXIoc2VnX3JpY2gsIHR5cGUgPT0gImluZGV4IiAmIGRwaSA9PSAiZDAyIiAmIHNlZ21lbnQgPT0gIkg5TjJfUEIyIiAmIGZlcnJldF93ZWlnaHQgPT0gIm9iZXNlIikKbCA9IGZpbHRlcihzZWdfcmljaCwgdHlwZSA9PSAiaW5kZXgiICYgZHBpID09ICJkMDIiICYgc2VnbWVudCA9PSAiSDlOMl9QQjIiICYgZmVycmV0X3dlaWdodCA9PSAibGVhbiIpCnQudGVzdChvJHNlZ19kZWxldGlvbl9yaWNobmVzcyxsJHNlZ19kZWxldGlvbl9yaWNobmVzcykKYGBgCgpgYGB7cn0Kc2VnX3JpY2ggJT4lIGZpbHRlcih0eXBlID09ICdpbmRleCcgJiAgc2VnbWVudCAlaW4lIFNFR01FTlRTKSAlPiUKICAgIHVuZ3JvdXAoKSAlPiUKICAgIHVuaXF1ZSgpICU+JQogICAgZ2dwbG90KC4sIGFlcyh4PXR5cGVfZGF5LCB5ID0gc2VnX2RlbGV0aW9uX3JpY2huZXNzLCBjb2xvciA9IHNlZ21lbnQsIGdyb3VwPXNlZ21lbnQpKSArIAogICAgI2dlb21fYm94cGxvdCgpICsgCiAgICBnZW9tX2xpbmUoc2l6ZSA9IDEpICsgCiAgICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAogICAgbGFicyh4PSdkcGkgKGJ5IGluZGV4IGNhc2UpJywgeT0nRFZHIHJpY2huZXNzJykgKyAKICAgIFBsb3RUaGVtZTEgKwogICAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAnU2V0MicpICsKICAgICN3ZWlnaHRfY29sU2NhbGUgKyAKICAgIGZhY2V0X2dyaWQoLn5mZXJyZXRfd2VpZ2h0ICsgZmVycmV0X2lkLCBzY2FsZXMgPSAnZnJlZScsIHNwYWNlID0gJ2ZyZWUnKQpgYGAKCmBgYHtyfQpwNCA9IHNlZ19yaWNoICU+JSBmaWx0ZXIoZmVycmV0X3dlaWdodCA9PSAnb2Jlc2UnICYgaW5kZXhfZGlyZWN0ID09ICdvYmVzZV9vYmVzZScgJiBzZWdtZW50ICVpbiUgU0VHTUVOVFMpICU+JQogICAgdW5ncm91cCgpICU+JQogICAgdW5pcXVlKCkgJT4lCiAgICBnZ3Bsb3QoLiwgYWVzKHg9dHlwZV9kYXksIHkgPSBzZWdfZGVsZXRpb25fcmljaG5lc3MsIGNvbG9yID0gc2VnbWVudCwgZ3JvdXA9c2VnbWVudCkpICsgCiAgICAjZ2VvbV9ib3hwbG90KCkgKyAKICAgIGdlb21fbGluZShzaXplID0gMSkgKyAKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiAgICBsYWJzKHg9J2RwaSAoYnkgaW5kZXggY2FzZSknLCB5PSdEVkcgcmljaG5lc3MnKSArIAogICAgUGxvdFRoZW1lMSArCiAgICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICdTZXQyJykgKwogICAgI3dlaWdodF9jb2xTY2FsZSArIAogICAgZmFjZXRfZ3JpZCgufnBhaXJfaWRzLCBzY2FsZXMgPSAnZnJlZScsIHNwYWNlID0gJ2ZyZWUnKQoKcHJpbnQocDQpCgoKZ2dzYXZlKHA0LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL3NlZ21lbnQub2Jlc2UudG8ub2Jlc2UucmljaG5lc3MucGRmIiksCiAgICAgICB3aWR0aCA9IDEyLAogICAgICAgaGVpZ2h0ID0gNCwgbGltaXRzaXplPUZBTFNFLCB1c2VEaW5nYmF0cyA9IEZBTFNFKQoKZ2dzYXZlKHA0LAogICAgICAgZmlsZW5hbWUgPSBnbHVlKCJ7d2tkaXJ9L0RWR19maWd1cmVzL3NlZ21lbnQub2Jlc2UudG8ub2Jlc2UucmljaG5lc3MucG5nIiksCiAgICAgICB3aWR0aCA9MTIsCiAgICAgICBoZWlnaHQgPSA0LCBsaW1pdHNpemU9RkFMU0UpICMsIHVzZURpbmdiYXRzID0gRkFMU0UpCmBgYAoKRW5kIG9mIEthdGUncyBjb2RlCgpXaGljaCBEVkdzIGFyZSBzaGFyZWQgYmV0d2VlbiBzdG9jayBhbmQgaW5kZXg/CmBgYHtyfQpyZXBzX2RmJERWRyA9IHBhc3RlMChyZXBzX2RmJHNlZ21lbnQsIl8iLHJlcHNfZGYkRFZHX2dyb3VwKQoKRjE3X3N0b2NrID0gZmlsdGVyKHJlcHNfZGYgLHR5cGUgPT0gInN0b2NrIiwgY29ob3J0ID09ICJGMTciKQpGMTdfc3RvY2tfZHZnID0gdW5pcXVlKEYxN19zdG9jayREVkcpClcxN19zdG9jayA9IGZpbHRlcihyZXBzX2RmICx0eXBlID09ICJzdG9jayIsIGNvaG9ydCA9PSAiVzE3IikKVzE3X3N0b2NrX2R2ZyA9IHVuaXF1ZShXMTdfc3RvY2skRFZHKQpTbTE4X3N0b2NrID0gZmlsdGVyKHJlcHNfZGYgLHR5cGUgPT0gInN0b2NrIiwgY29ob3J0ID09ICJTbTE4IikKU20xOF9zdG9ja19kdmcgPSB1bmlxdWUoU20xOF9zdG9jayREVkcpClNwMTlfc3RvY2sgPSBmaWx0ZXIocmVwc19kZiAsdHlwZSA9PSAic3RvY2siLCBjb2hvcnQgPT0gIlNwMTkiKQpTcDE5X3N0b2NrX2R2ZyA9IHVuaXF1ZShTcDE5X3N0b2NrJERWRykKU3AyMF9zdG9jayA9IGZpbHRlcihyZXBzX2RmICx0eXBlID09ICJzdG9jayIsIGNvaG9ydCA9PSAiU3AyMCIpClNwMjBfc3RvY2tfZHZnID0gdW5pcXVlKFNwMjBfc3RvY2skRFZHKQoKRjE3X2luZGV4ID0gZmlsdGVyKHJlcHNfZGYgLHR5cGUgPT0gImluZGV4IiwgY29ob3J0ID09ICJGMTciKQpGMTdfaW5kZXhfZHZnID0gdW5pcXVlKEYxN19pbmRleCREVkcpClcxN19pbmRleCA9IGZpbHRlcihyZXBzX2RmICx0eXBlID09ICJpbmRleCIsIGNvaG9ydCA9PSAiVzE3IikKVzE3X2luZGV4X2R2ZyA9IHVuaXF1ZShXMTdfaW5kZXgkRFZHKQpTbTE4X2luZGV4ID0gZmlsdGVyKHJlcHNfZGYgLHR5cGUgPT0gImluZGV4IiwgY29ob3J0ID09ICJTbTE4IikKU20xOF9pbmRleF9kdmcgPSB1bmlxdWUoU20xOF9pbmRleCREVkcpClNwMTlfaW5kZXggPSBmaWx0ZXIocmVwc19kZiAsdHlwZSA9PSAiaW5kZXgiLCBjb2hvcnQgPT0gIlNwMTkiKQpTcDE5X2luZGV4X2R2ZyA9IHVuaXF1ZShTcDE5X2luZGV4JERWRykKU3AyMF9pbmRleCA9IGZpbHRlcihyZXBzX2RmICx0eXBlID09ICJpbmRleCIsIGNvaG9ydCA9PSAiU3AyMCIpClNwMjBfaW5kZXhfZHZnID0gdW5pcXVlKFNwMjBfaW5kZXgkRFZHKQoKRjE3X3NoYXJlZCA9IEYxN19pbmRleCAlPiUgZmlsdGVyKERWRyAlaW4lIEYxN19zdG9ja19kdmcpICU+JSBmaWx0ZXIoKERWRyAlaW4lIEYxN19pbmRleF9kdmcpKSAlPiUgdW5pcXVlKCkKRjE3X2Rlbm92byA9IEYxN19pbmRleCAlPiUgZmlsdGVyKChEVkcgJWluJSBGMTdfaW5kZXhfZHZnKSkgJT4lIGZpbHRlcighKERWRyAlaW4lIEYxN19zdG9ja19kdmcpKSAlPiUgdW5pcXVlKCkKClcxN19zaGFyZWQgPSBXMTdfaW5kZXggJT4lIGZpbHRlcihEVkcgJWluJSBXMTdfc3RvY2tfZHZnKSAlPiUgZmlsdGVyKChEVkcgJWluJSBXMTdfaW5kZXhfZHZnKSkgJT4lIHVuaXF1ZSgpClcxN19kZW5vdm8gPSBXMTdfaW5kZXggJT4lIGZpbHRlcigoRFZHICVpbiUgVzE3X2luZGV4X2R2ZykpICU+JSBmaWx0ZXIoIShEVkcgJWluJSBXMTdfc3RvY2tfZHZnKSkgJT4lIHVuaXF1ZSgpCgpTbTE4X3NoYXJlZCA9IFNtMThfaW5kZXggJT4lIGZpbHRlcihEVkcgJWluJSBTbTE4X3N0b2NrX2R2ZykgJT4lIGZpbHRlcigoRFZHICVpbiUgU20xOF9pbmRleF9kdmcpKSAlPiUgdW5pcXVlKCkKU20xOF9kZW5vdm8gPSBTbTE4X2luZGV4ICU+JSBmaWx0ZXIoKERWRyAlaW4lIFNtMThfaW5kZXhfZHZnKSkgJT4lIGZpbHRlcighKERWRyAlaW4lIFNtMThfc3RvY2tfZHZnKSkgJT4lIHVuaXF1ZSgpCgpTcDE5X3NoYXJlZCA9IFNwMTlfaW5kZXggJT4lIGZpbHRlcihEVkcgJWluJSBTcDE5X3N0b2NrX2R2ZykgJT4lIGZpbHRlcigoRFZHICVpbiUgU3AxOV9pbmRleF9kdmcpKSAlPiUgdW5pcXVlKCkKU3AxOV9kZW5vdm8gPSBTcDE5X2luZGV4ICU+JSBmaWx0ZXIoKERWRyAlaW4lIFNwMTlfaW5kZXhfZHZnKSkgJT4lIGZpbHRlcighKERWRyAlaW4lIFNwMTlfc3RvY2tfZHZnKSkgJT4lIHVuaXF1ZSgpCgpTcDIwX3NoYXJlZCA9IFNwMjBfaW5kZXggJT4lIGZpbHRlcihEVkcgJWluJSBTcDIwX3N0b2NrX2R2ZykgJT4lIGZpbHRlcigoRFZHICVpbiUgU3AyMF9pbmRleF9kdmcpKSAlPiUgdW5pcXVlKCkgIyBzdGlsbCBub3Qgd29ya2luZwpTcDIwX2Rlbm92byA9IFNwMjBfaW5kZXggJT4lIGZpbHRlcigoRFZHICVpbiUgU3AyMF9pbmRleF9kdmcpKSAlPiUgZmlsdGVyKCEoRFZHICVpbiUgU3AyMF9zdG9ja19kdmcpKSAlPiUgdW5pcXVlKCkgIyBzdGlsbCBub3Qgd29ya2luZwoKc3RvY2tfc2hhcmVkID0gcmJpbmQoRjE3X3NoYXJlZCxXMTdfc2hhcmVkLFNtMThfc2hhcmVkLFNwMTlfc2hhcmVkLFNwMjBfc2hhcmVkKQppbmRleF91bmlxdWUgPSByYmluZChGMTdfZGVub3ZvLFcxN19kZW5vdm8sU20xOF9kZW5vdm8sU3AxOV9kZW5vdm8sU3AyMF9kZW5vdm8pCmBgYAoKYGBge3J9CnN0b2NrX29iZXNlID0gZmlsdGVyKHN0b2NrX3NoYXJlZCwgZmVycmV0X3dlaWdodCA9PSAib2Jlc2UiKSAKb19kdmcgPSB1bmlxdWUoc3RvY2tfb2Jlc2UkRFZHKQoKc3RvY2tfbGVhbiA9IGZpbHRlcihzdG9ja19zaGFyZWQsIGZlcnJldF93ZWlnaHQgPT0gImxlYW4iKSAKbF9kdmcgPSB1bmlxdWUoc3RvY2tfbGVhbiREVkcpCgpzdG9ja19kdmcgPC0gbGlzdChPYmVzZSA9IG9fZHZnLCBMZWFuID0gbF9kdmcpCgpTdG9ja0RWR3MgPSBnZ1Zlbm5EaWFncmFtKHN0b2NrX2R2ZykKcHJpbnQoU3RvY2tEVkdzKQpnZ3NhdmUoU3RvY2tEVkdzLCBmaWxlID0gIlN0b2NrRFZHcy5wZGYiLCBwYXRoID0gc2F2ZWl0ZGlyKQoKU2hvY2tTaGFyZWREVkdzID0gZ2dwbG90KHN0b2NrX3NoYXJlZCwgYWVzKHggPSBkcGksIHkgPSBEVkcpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gRFZHKSkgKwogIGZhY2V0X2dyaWQofnNlZ21lbnQpICsKICBQbG90VGhlbWUxCnByaW50KFNob2NrU2hhcmVkRFZHcykKZ2dzYXZlKFNob2NrU2hhcmVkRFZHcywgZmlsZSA9ICJTaG9ja1NoYXJlZERWR3MucGRmIiwgcGF0aCA9IHNhdmVpdGRpcikKYGBgCkFyZSB0aGVyZSBkaWV0LXNwZWNpZmljIERWR3MgaW4gaW5kZXggZmVycmV0cz8KYGBge3J9CmluZGV4X29iZXNlID0gZmlsdGVyKGluZGV4X3VuaXF1ZSwgZmVycmV0X3dlaWdodCA9PSAib2Jlc2UiKSAKb19kdmcgPSB1bmlxdWUoaW5kZXhfb2Jlc2UkRFZHKQoKaW5kZXhfbGVhbiA9IGZpbHRlcihpbmRleF91bmlxdWUsIGZlcnJldF93ZWlnaHQgPT0gImxlYW4iKSAKbF9kdmcgPSB1bmlxdWUoaW5kZXhfbGVhbiREVkcpCgpkaWV0X2R2ZyA8LSBsaXN0KE9iZXNlID0gb19kdmcsIExlYW4gPSBsX2R2ZykKCkRpZXRVbmlxdWVEVkdzID0gZ2dWZW5uRGlhZ3JhbShkaWV0X2R2ZykKcHJpbnQoRGlldFVuaXF1ZURWR3MpCmdnc2F2ZShEaWV0VW5pcXVlRFZHcywgZmlsZSA9ICJEaWV0VW5pcXVlRFZHcy5wZGYiLCBwYXRoID0gc2F2ZWl0ZGlyKQpgYGAKClB1bGxpbmcgb3V0IGRpZXQtc3BlY2lmaWMgRFZHcwpgYGB7cn0KbGVhbiA9IGluZGV4X2xlYW4gJT4lIAogIGZpbHRlcihEVkcgJWluJSBsX2R2ZykgJT4lIAogIGZpbHRlcighKERWRyAlaW4lIG9fZHZnKSkgJT4lCiAgdW5pcXVlKCkKCmxlYW4gPSBsZWFuICU+JQogIGdyb3VwX2J5KERWRykgJT4lIAogIG11dGF0ZShjb3VudCA9IDEsIHRvdGFsc2FtcCA9IHN1bShjb3VudCkpCgptdWx0X2xlYW4gPSBmaWx0ZXIobGVhbiwgdG90YWxzYW1wID4gMSkgJT4lIAogIHVuaXF1ZSgpCgpvYmVzZSA9IGluZGV4X3VuaXF1ZSAlPiUgCiAgZmlsdGVyKChEVkcgJWluJSBvX2R2ZykpICU+JQogIGZpbHRlcighKERWRyAlaW4lIGxfZHZnKSkgJT4lIAogIHVuaXF1ZSgpCgpvYmVzZSA9IG9iZXNlICU+JQogIGdyb3VwX2J5KERWRykgJT4lIAogIG11dGF0ZShjb3VudCA9IDEsIHRvdGFsc2FtcCA9IHN1bShjb3VudCkpCgptdWx0X29iZXNlID0gZmlsdGVyKG9iZXNlLCB0b3RhbHNhbXAgPiAxKSAlPiUgCiAgdW5pcXVlKCkKYGBgCgpgYGB7cn0KZ2dwbG90KGxlYW4sIGFlcyh4ID0gRFZHKSkgKwogIGdlb21faGlzdG9ncmFtKHN0YXQgPSAiY291bnQiKQoKTGVhbkRWR3MgPSBnZ3Bsb3QobGVhbiwgYWVzKHkgPSBEVkcpKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IE5ld1N0YXJ0KSkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBOZXdFbmQpKSArCiAgZmFjZXRfZ3JpZCh+ZmFjdG9yKHNlZ21lbnQsIGxldmVscyA9IFNFR01FTlRTKSkgKwogIFBsb3RUaGVtZTEKcHJpbnQoTGVhbkRWR3MpCmdnc2F2ZShMZWFuRFZHcywgZmlsZSA9ICJMZWFuRFZHcy5wZGYiLCBwYXRoID0gc2F2ZWl0ZGlyKQoKZ2dwbG90KGxlYW4sIGFlcyh4ID0gZHBpLCB5ID0gRFZHKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IERWRykpICsKICBmYWNldF9ncmlkKH5mYWN0b3Ioc2VnbWVudCwgbGV2ZWxzID0gU0VHTUVOVFMpKSArCiAgUGxvdFRoZW1lMQoKZ2dwbG90KG11bHRfbGVhbiwgYWVzKHggPSBkcGksIHkgPSBEVkcpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gRFZHKSkgKwogIGZhY2V0X2dyaWQofmZhY3RvcihzZWdtZW50LCBsZXZlbHMgPSBTRUdNRU5UUykpICsKICBQbG90VGhlbWUxCgpnZ3Bsb3Qob2Jlc2UsIGFlcyh4ID0gRFZHKSkgKwogIGdlb21faGlzdG9ncmFtKHN0YXQgPSAiY291bnQiKQoKT2Jlc2VEVkdzID0gZ2dwbG90KG9iZXNlLCBhZXMoeSA9IERWRykpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gTmV3U3RhcnQpKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IE5ld0VuZCkpICsKICBmYWNldF9ncmlkKH5mYWN0b3Ioc2VnbWVudCwgbGV2ZWxzID0gU0VHTUVOVFMpKSArCiAgUGxvdFRoZW1lMQpwcmludChPYmVzZURWR3MpCmdnc2F2ZShPYmVzZURWR3MsIGZpbGUgPSAiT2Jlc2VEVkdzLnBkZiIsIHBhdGggPSBzYXZlaXRkaXIpCgpnZ3Bsb3Qob2Jlc2UsIGFlcyh4ID0gZHBpLCB5ID0gRFZHKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IERWRykpICsKICBmYWNldF9ncmlkKH5mYWN0b3Ioc2VnbWVudCwgbGV2ZWxzID0gU0VHTUVOVFMpKSArCiAgUGxvdFRoZW1lMQoKZ2dwbG90KG11bHRfb2Jlc2UsIGFlcyh4ID0gZHBpLCB5ID0gRFZHKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IERWRykpICsKICBmYWNldF9ncmlkKH5mYWN0b3Ioc2VnbWVudCwgbGV2ZWxzID0gU0VHTUVOVFMpKSArCiAgUGxvdFRoZW1lMQpgYGAKYGBge3J9CgpgYGAKQXJlIERWR3MgdHJhbnNtaXR0ZWQKYGBge3J9CmdncGxvdChyZXBzX2RmLCBhZXMoeCA9ICkpCmBgYA==